摘自:
《Effcitive Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法》
第37条:理解“块”这一概念
Block (块)
块类型的语法结构如下:
return_type (^block_name) (parameters)
______________________________________________________________________________________
在BDN代码里看到一句:
typedef void(^BDNCouponQueryViewControllerQueryCompletion)(BDNBaseViewController *viewController);
这句话的意思是,定义了一个block:
block名为BDNCouponQueryViewControllerQueryCompletion
参数是BDNBaseViewController对象
返回为void
使用方法:
@property (nonatomic, copy) BDNCouponQueryViewControllerQueryCompletion queryCompletion;
可以看到这个block,可以作为类型来定义新的对象
______________________________________________________________________________________
e.g.
定义一个加法block,输入两个int,输出一个int
定义:
int (^addBlock) (int a, int b) = ^(int a, int b){ return a + b; };
注意:最后有个分号,应为这只是一个定义语句,而不是一个方法块
使用:
int add = addBlock(2, 3);
可以看出,长得很像函数指针。
块可以捕获其声明范围内的所有变量
默认情况下,为块捕获的变量,是不可在块中修改的
但如果在声明变量前加上__block修饰符,就可以在块内修改
内联块
e.g.
NSArray *array = @[@0, @1, @2, @3, @4, @5]; __block NSInteger count = 0; [array enumerateObjectsUsingBlock:^(NSNumber *number, NSUInteger idx, BOOL *stop) { if ([number compare:@2] == NSOrderedAscending) { count ++; } }]; NSLog(@"%ld", (long)count);
所谓内联块,指的是,如上所示,传给 enumerateObjectsUsingBlock: 方法的块之前并未先赋值给局部变量,而是直接内联在函数调用里面。
如果块捕获的变量是对象类型,则会自动保留
块同其它对象一样,有引用计数
当最后一个指向块的引用移走后,块就回收了
回收的同时也会释放块所捕获的变量,以便平衡捕获时所执行的保留操作