- Block 也是一种 Objective-C 对象,可以用于赋值,当做参数传递,当做返回值,也可以放入 NSArray 和 NSDictionary 中。
1>. 如果是局部变量,Block是值传递
int a = 3;
void (^closure)() = ^{
NSLog(@"a = %d",a);
};
a = 5;
closure(); // a = 3;
2>. 如果是静态变量,全局变量,__block修饰的变量, Block是指针传递
static int a = 3;
void (^closure)() = ^{
NSLog(@"a = %d",a);
};
a = 5;
closure(); // a = 5;
3.1> . 解决循环引用
@property (nonatomic , strong) void (^ failureBlock)();
__weak typeof(self) weakSelf = self;
_failureBlock = ^(){
__strong typeof(weakSelf) strongSelf = weakSelf;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@",strongSelf);
});
};
_failureBlock();
解释:1. _failureBlock 会对外面所有的‘强指针对象’进行强引用,包括 ‘self’ 对象 , 所以要在 外面用 __weak 声明一个弱指针类型的 self 供代码块里面使用。 2. 代码块中为什么要用 “__strong” 在抢引用 一次 “weakSelf” ,是为了防止在执行 “dispatch_after” 时 weakSelf 变成 nil.
3.2>
__weak __typeof__(self) weakSelf = self;
NSBlockOperation *op = [[NSBlockOperation alloc] init] ;
[ op addExecutionBlock:^ {
__strong __typeof__(self) strongSelf = weakSelf;
[strongSelf doSomething];
[strongSelf doMoreThing];}
];
[someOperationQueue addOperation:op];
__strong这一句在执行的时候,如果 WeakSelf 还没有变成 nil,那么就会 retain self,让 self 在 block 执行期间不会变为 nil。
这样上面的 doSomething和 doMoreThing 要么全执行成功,要么全失败,不会出现一个成功一个失败,即执行到中间 self变成 nil 的情况。 如果想全部执行成功,可以用block 在引用一次。
总结 :Block 会对里面所有的外部的所有 ’强指针’ 进行全部‘强引用’。
blcok作为返回值的使用情况
参考下masonry框架的demo;
[blueView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.and.height.equalTo(redView);//使宽高等于 redView
}];
make.width.and.height.equalTo(redView);
“equalTo” 的返回值就是 “Block”,然后在调用block,传入参数redView. 想必这种链式语法大家都很喜欢。下面是一个简单的小例子。
Calculate.h
@interface Calculate : NSObject
@property (nonatomic, readonly) double result;
-(Calculate * (^)(double number))plus;
@end
Calculate.m
@interface Calculate ()
@property (nonatomic, readwrite) double result;
@end
@implementation Calculate
- (Calculate * (^)(double number))plus{
return ^(double num){
_result += num;
return self;
};
}
@end
调用的时候:
Calculate *cal = [Calculate new];
double res = cal.plus(1).plus(2).plus(3).result;
NSLog(@"%f",res); // 6.000000
可以一直用点语法一直plus,最后可以直接调用result得到我们的计算结果。
最后看一下怎么快速调用block,学过前端的同事感觉是不是很熟悉。
(^(UIColor * backgroundColor){
self.view.backgroundColor = backgroundColor;
})([UIColor redColor]);
那么上面 "3.2>"的要想全部成功就可以这么写。
__weak __typeof__(self) weakSelf = self;
NSBlockOperation *op = [[NSBlockOperation alloc] init] ;
[ op addExecutionBlock:^ {
__strong __typeof__(self) strongSelf = weakSelf;
(^{
[strongSelf doSomething];
[strongSelf doMoreThing];
})();
}];
[someOperationQueue addOperation:op];
这样就会自动强引用“ strongSelf”。