- Block 也是一種 Objective-C 對(duì)象,可以用于賦值,當(dāng)做參數(shù)傳遞端铛,當(dāng)做返回值,也可以放入 NSArray 和 NSDictionary 中疲眷。
1>. 如果是局部變量禾蚕,Block是值傳遞
int a = 3;
void (^closure)() = ^{
NSLog(@"a = %d",a);
};
a = 5;
closure(); // a = 3;
2>. 如果是靜態(tài)變量,全局變量狂丝,__block修飾的變量换淆, Block是指針傳遞
static int a = 3;
void (^closure)() = ^{
NSLog(@"a = %d",a);
};
a = 5;
closure(); // a = 5;
3.1> . 解決循環(huán)引用
@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 會(huì)對(duì)外面所有的‘強(qiáng)指針對(duì)象’進(jìn)行強(qiáng)引用哗总,包括 ‘self’ 對(duì)象 , 所以要在 外面用 __weak 聲明一個(gè)弱指針類型的 self 供代碼塊里面使用。 2. 代碼塊中為什么要用 “__strong” 在搶引用 一次 “weakSelf” 产舞,是為了防止在執(zhí)行 “dispatch_after” 時(shí) 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這一句在執(zhí)行的時(shí)候魂奥,如果 WeakSelf 還沒有變成 nil,那么就會(huì) retain self易猫,讓 self 在 block 執(zhí)行期間不會(huì)變?yōu)?nil耻煤。
這樣上面的 doSomething和 doMoreThing 要么全執(zhí)行成功,要么全失敗准颓,不會(huì)出現(xiàn)一個(gè)成功一個(gè)失敗哈蝇,即執(zhí)行到中間 self變成 nil 的情況。 如果想全部執(zhí)行成功攘已,可以用block 在引用一次炮赦。
總結(jié) :Block 會(huì)對(duì)里面所有的外部的所有 ’強(qiáng)指針’ 進(jìn)行全部‘強(qiáng)引用’。
blcok作為返回值的使用情況
參考下masonry框架的demo样勃;
[blueView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.and.height.equalTo(redView);//使寬高等于 redView
}];
make.width.and.height.equalTo(redView);
“equalTo” 的返回值就是 “Block”吠勘,然后在調(diào)用block,傳入?yún)?shù)redView. 想必這種鏈?zhǔn)秸Z法大家都很喜歡峡眶。下面是一個(gè)簡(jiǎn)單的小例子剧防。
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
調(diào)用的時(shí)候:
Calculate *cal = [Calculate new];
double res = cal.plus(1).plus(2).plus(3).result;
NSLog(@"%f",res); // 6.000000
可以一直用點(diǎn)語法一直plus,最后可以直接調(diào)用result得到我們的計(jì)算結(jié)果。
最后看一下怎么快速調(diào)用block辫樱,學(xué)過前端的同事感覺是不是很熟悉峭拘。
(^(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];
這樣就會(huì)自動(dòng)強(qiáng)引用“ strongSelf”狮暑。