编写高质量代码的52个有效方法

52个有效方法(37) - 理解“块”这一概念

2018-09-14  本文已影响6人  SkyMing一C

块的基础知识

块类型的语法结构
return_type (^block_name)(parameters)//返回类型 (^声明的block名称)(参数列表)
^{
    //Block implementation here
}
void (^someBlock)() = ^{
    //Block implementation here
};
int additional = 5;
int (^addBlock)(int a, int b) = ^(int a, int b){
    return a + b + additional;
};

int add = addBlock(2, 5);
NSArray *array = @[@0, @1, @2, @3, @4, @5];
__block NSInteger count = 0;
[array enumerateObjectsUsingBlock:^(NSNumber *  _Nonnull number, NSUInteger idx, BOOL * _Nonnull stop) {
    if ([number compare:@2] == NSOrderedAscending) {
        count++;
    }
}];
//count = 2

“内联块”(inline block)

这段范例代码也演示了“内联块”(inline block)的用法。传给“enumberateObjectsUsingBlock”方法的块并未先赋值给变量,而是直接内联在函数调用里了。

块的内部结构

块的内部结构

全局块、栈块及堆块

void (^block)();
if (/* some condition */) {
    block = ^{
        NSLog(@"Block A");
    };
}else{
    block = ^{
        NSLog(@"Block B");
    };
}
block();

定义在if及else语句中的两个块都分配在栈内存中。编译器会给每个块分配好栈内存,然而等离开了相应范围后,编译器可能把分配给块的内容覆写掉,于是运行时可能会程序崩溃。

void (^block)();
if (/* some condition */) {
    block = [^{
        NSLog(@"Block A");
    }; copy];
}else{
    block = [^{
        NSLog(@"Block B");
    }; copy];
}
block();
void (^block)() = ^{
    NSLog(@"This is a block");
};

运行全局块所需的全部信息都能在编译期确定。

要点
  1. 块是C、C++、Objective-C中的词法闭包。

  2. 块可接受参数,也可返回值。

  3. 块可以分配在栈或堆上,也可以是全局的。分配在栈上的块可拷贝到堆里,这样的话,就和标准的Objective-C对象一样,具备引用计数了。

上一篇下一篇

猜你喜欢

热点阅读