block语法结构:
返回值类型(^block变量名)(形参列表) = ^(形参列表) {
};
NSString *(^logBlock)(NSString *,NSString *) = ^(NSString *str1, NSString *str2){
return [NSString stringWithFormat:@"%@%@", str1, str2];
};
//调用logBlock,输出的是 我是Block
NSLog(@"%@", logBlock(@"我是", @"Block"));
block的强大之处:在声明它的范围里,所有变量都可以为其所捕获。
默认情况下,为块所捕获的变量,是不可以在块里修改的
- (void)viewDidLoad {
//将Block定义在方法内部
int x = 100;
void (^sumXAndYBlock)(int) = ^(int y){
x = x+y;
printf("new x value is %d",x);
};
sumXAndYBlock(50);
}
Xcode会提示x变量错误信息:Variable is not assigning (missing __block type),这时候给int x = 100;语句前面加上__block关键字即可:
__block int x = 100;
block的typedef
结构:
typedef 返回值类型 (^newBlockTypeName)(参数列表);
//定义一个有参有返回值的block的别名
typedef int (^myBlock)(int, int);
//此时myBlock是一个类型,不再是一个单纯的变量了
myBlock b1 = ^(int a, int b){
return a + b;
};
NSLog(@"a + b = %d", b1(1,2));
另一例:
- (void)startWithCompletionHandler:(void(^)(NSData *data, NSError *error))completion;
用typedef后:好处一是易于理解,二是当block需要再加一个参数,你只需要更改typedef即可。
typedef void(^XJ_CompletionHandler) (NSData *data, NSError *error);
- (void)startWithCompletionHandler:(XJ_CompletionHandler)completion;
block的循环引用问题
即使在你的block代码中没有显式地出现"self",也会出现循环引用!只要你在block里用到了self所拥有的东西。
__weak typeof(self) weakSelf = self;
self.blockA = ^{
__strong typeof(weakSelf) strongSelf = weakSelf;//加一下强引用,避免weakSelf被释放掉
NSLog(@"%@", strongSelf->_xxView); //不会导致循环引用.
};