Block

1.Block的基本用法

(1)无返回值,无形参

    // void代表block将来保存的代码没有返回值
    // ()代表block将来保存的代码没有形参
    // (^roseBlock) 代表reseBlock是一个block变量, 可以用于保存一段block代码
    void (^roseBlock) ();
    // 如果block没有参数, 那么^后面的()可以省略
    roseBlock = ^(){
        printf("  {@} \n");
        printf("   |  \n");
        printf("  \\|/ \n");
        printf("   | \n");
    };
   // 要想执行block保存的代码, 必须调用block才会执行
    roseBlock();

(2)无返回值,有形参

void (^roseBlock) (int);
    roseBlock = ^(int num){
        for (int i = 0; i < num; ++i) {
            
            printf("  {@} \n");
            printf("   |  \n");
            printf("  \\|/ \n");
            printf("   | \n");
        }
    
    };
    
    roseBlock(2);

(3)有返回值,有形参

    int (^sumBlock) (int, int);
    sumBlock =^(int value1, int value2){
        return value1 + value2;
    };
    NSLog(@"sum = %i", sumBlock(10, 40));

2.利用typedef给block起别名

// 在函数外面定义
typedef int (^calculteBlock)(int , int);

 calculteBlock sumBlock = ^(int value1, int value2){
        return value1 + value2;
    };
    NSLog(@"sum = %i", sumBlock(20, 10));
    
 calculteBlock minusBlock = ^(int value1, int value2){
        return value1 - value2;
    };

3.Block的注意事项

(1)block中可以访问外面的变量

    int a = 10;
    void (^myBlock)() = ^{
        NSLog(@"a = %i", a);
    };
    myBlock();
     

(2)block中可以定义和外界同名的变量, 并且如果在block中定义了和外界同名的变量, 在block中访问的是block中的变量

    int a = 10;
    void (^myBlock)() = ^{
        int a  = 20;
        NSLog(@"a = %i", a);
    };
    myBlock();

(3)默认情况下, 不可以在block中修改外界变量的值
如果没有添加__block是值传递,如果加上__block之后就是地址传递, 所以可以在block中修改外界变量的值

    // 因为block中的变量和外界的变量并不是同一个变量
    // 如果block中访问到了外界的变量, block会将外界的变量拷贝一份到堆内存中
    // 因为block中使用的外界变量是copy的, 所以在调用之前修改外界变量的值, 不会影响到block中copy的值
    int a = 10;
    NSLog(@"&a = %p", &a);
    void (^myBlock)() = ^{
        a = 50;
        NSLog(@"&a = %p", &a);
        NSLog(@"a = %i", a);
    };
    a = 20;
    myBlock();


    // 如果想在block中修改外界变量的值, 必须在外界变量前面加上__block
    // 如果在block中修改了外界变量的值, 会影响到外界变量的值
    __block int a = 10;
    NSLog(@"&a = %p", &a);
    void (^myBlock)() = ^{
        a = 50;
        NSLog(@"&a = %p", &a);
        NSLog(@"a = %i", a);
    };
    myBlock();
    NSLog(@"a = %i", a);

4.通过block逆向传值

逆传:用block来传值,处理网络的时候经常使用block封装代码。
请求网络数据(延迟) 先把展示到控件的代码先保存到block,等请求到数据的时候直接调用Block
A文件(用来保存block代码):

 addVc.block = ^(XMGContact *contact){
        // 1.联系人添加到数组
        [self.contacts addObject:contact];
        // 2.刷新表格
        [self.tableView reloadData];
    };

B文件(逆传):

.h文件
// 利用block传值,需要把什么传递出去,就作为block参数,通常不需要返回值
typedef void(^XMGAddViewControllerBlock)(XMGContact *contact);
@property (nonatomic, strong) XMGAddViewControllerBlock block;

.m文件
// 0.把文本框的值包装成联系人模型
    XMGContact *c = [XMGContact contactWithName:_nameField.text phone:_phoneField.text];
   
    // 1.把联系人添加到联系人控制器的数组,让联系人控制器刷新表格
    if (_block) {
        _block(c);
    }
    
    // 2.回到联系人控制器
    [self.navigationController popViewControllerAnimated:YES];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容