• Block的基本用法


    NSString* (^myBlock)(NSString*, int);
    
    myBlock = ^(NSString *name, int age){
        return [NSString stringWithFormat:@"My name is %@,I‘m %d years old!",name,age];
    };
    
    NSString *str = myBlock(@"胡晓伟",31);
    NSLog(@"%@",str);

    上面的例子演示了Block的基本用法,Block声明的基本结构是:

    返回类型 (^变量名)(参数列表..)

    例如:

    void (^myBlock1)(void);  //无返回值,无参数
    void (^myBlock2)(NSObject, int); //有返回值,有参数
    NSString* (^myBlock3)(NSString* name, int age); //有返回值和参数,并且在参数类型后面加入了参数名(仅为可读性)

    将一个Block定义为函数参数:

    - (void)testBlock:(NSString *(^)(void)) myName
    {
        NSLog(@"My Name is %@",myName());
    }
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        NSString *(^myBlock)(void) = ^{ return @"wayne"; };
        
        [self testBlock:myBlock];
        
        return YES;
    }

    下面看看如何通过Block访问不同上下文环境的局部变量:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        NSString *str = @"AAA";
        
        NSString *(^myBlock)(void) = ^(void){
            return str;
        };
    
        [self logBlock:myBlock];
        
        return YES;
    }
    
    - (void)logBlock:(NSString *(^)(void))block
    {
        NSLog(@"%@",block());
    }

    下面的代码测试了可变对象与不可变对象在Block中的情况:

    NSString *str1 = @"str1";
    NSMutableString *str2 = [NSMutableString stringWithString:@"str2"];
    
    NSLog(@"************初始值与初始地址************");
    NSLog(@"【%@】,【%p】",str1,&str1);
    NSLog(@"【%@】,【%p】",str2,&str2);
    
    void (^myBlock)(void) = ^{
        NSLog(@"************Block中输出************");
        NSLog(@"【%@】,【%p】",str1,&str1);
        NSLog(@"【%@】,【%p】",str2,&str2);
    };
    
    str1 = @"str1_update";
    [str2 appendString:@"_update"];
    NSLog(@"************更新后的值与地址************");
    NSLog(@"【%@】,【%p】",str1,&str1);
    NSLog(@"【%@】,【%p】",str2,&str2);
    
    myBlock();
    
    NSLog(@"************调用Block后的值与地址************");
    NSLog(@"【%@】,【%p】",str1,&str1);
    NSLog(@"【%@】,【%p】",str2,&str2);

    输出结果:

    ************初始值与初始地址************
    
    【str1】,【0xbff4d1f8】
    
    【str2】,【0xbff4d1f4************更新后的值与地址************
    
    【str1_update】,【0xbff4d1f8】
    
    【str2_update】,【0xbff4d1f4************Block中输出************
    
    【str1】,【0xbff4d1e4】
    
    【str2_update】,【0xbff4d1e8************调用Block后的值与地址************
    
    【str1_update】,【0xbff4d1f8】
    
    【str2_update】,【0xbff4d1f4

    可以看出在Block内,不可变对象的值任然是初始化时的值,可变对象的值变成了新值。这是因为Block初始化在前,可变对象的修改在后;如果颠倒顺序,先修改可变对象的值,再初始化Block,这样Block就能同步修改后的值了。

    最后看看Block对变量的访问权限:

    #import "AppDelegate.h"
    
    @interface AppDelegate ()
    {
        NSString *str1;
    }
    @end
    
    @implementation AppDelegate
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        NSString *str2 = @"str2";
        
        __block NSString *str3 = @"str3";
        
        void (^myBlock)(void) = ^{
            
            str1 = @"newString"; //ok
            
            //str2 = @"newString"; //error
            
            str3 = @"newString"; //ok
    
            NSLog(@"%@,%@,%@",str1,str2,str3);
        };
    
        myBlock();
        
        return YES;
    }

    在Block里不能直接修改局部变量的值,如果要修改,需要在局部变量前加上修饰关键字__block。

    从上面的例子可以看到在Block里能访问并修改类变量、带__block关键字的变量;但是不能修改不带__block关键字的局部变量。

     

     

  • 相关阅读:
    EntityFramework 数据库的迁移
    free之后将指针置为NULL
    结构体对齐及#pragma详细解释
    大端小端
    TCP封包解包---如有错误,请纠正!
    堆栈----好久没有更新了
    附近点搜索
    LRU Cache
    电商的秒杀和抢购
    搜索关键词智能提示suggestion
  • 原文地址:https://www.cnblogs.com/CoderWayne/p/4026313.html
Copyright © 2020-2023  润新知