小技巧:block的書寫格式的快捷方式,可直接敲inlineBlock
,如下圖:
3.png
22.png
一、block的聲明、定義
如果不用strong
,block會被銷毀
// block:ARC使用strong,非ARC使用copy
// block類型:void(^)()
@property (nonatomic, strong) void(^operation)();
二、block的作用
保存一份代碼,等到恰當時機才會調用
三、block在開發中使用的場景
- 場景一:將block保存到對象中,在恰當的時機才會調用(如:彩票)
- (void)block1
{
Person *p = [[Person alloc] init];
void(^block)() = ^() {
NSLog(@"執行對象中block");
};
p.operation = ^(){
NSLog(@"執行對象中block");
};
p.operation = block;
_p = p;
}
其中代碼p.operation = block;
與下面代碼是一樣的,寫哪種都可以
p.operation = ^(){
NSLog(@"執行對象中block");
};
- 場景二:把block當做方法的參數使用,參數類型就是block類型。外界不調用,都是方法內部去調用,方法實現交給外界決定
1、在person .h中聲明方法
// 參數類型:block類型
- (void)eat:(void(^)())block;
如果上面這種方式看不懂,可以給block取個別名,如下:
// name:類型的別名
typedef void(^BlockName)();
- (void)eat:(BlockName)block;
上面兩種方式,效果是一樣的,都是傳一個block參數
2、下面代碼是在viewController
中傳參數,但是還沒有調用,具體的代碼如下:
- (void)block2
{
Person *p = [[Person alloc] init];
void(^block)() = ^{
NSLog(@"吃東西");
};
[p eat:block];
// 傳入block給參數的Block賦值
[p eat:^{
NSLog(@"吃東西");
}];
}
同(場景一)一樣其中代碼[p eat:block];
與下面代碼是一樣的,寫哪種都可以
// 傳入block給參數的Block賦值
[p eat:^{
NSLog(@"吃東西");
}];
3、在person.m
中調用這個方法。其實在viewController
中傳的參數相當于給person.m
中調用的block賦值,即person.m
的block值就是viewController
傳的參數
- (void)eat:(void (^)())block
{
/**
block = ^{
NSLog(@"吃東西");
};
*/
block();
}
- 場景三、把block當做方法的返回值,目的就是為了代替方法,block交給內部實現,外界不需要知道block是怎么實現的,只管調用
想調用p.run方法就必須有返回值(getter方法要有返回值)。
1、在person.h
中,run的返回值類型是block
- (void(^)(int))run;
2、在person.m
中實現這個方法
- 這個是沒有參數
- (void (^)())run
{
return ^(){
NSLog(@"跑了%d米");
};
}
- 這個是有參數
- (void (^)(int))run
{
return ^(int meter){
NSLog(@"跑了%d米",meter);
};
}
3、在viewController.m
中只管調用這個方法,不需要知道具體是怎么實現的
- (void)block3
{
Person *p = [[Person alloc] init];
[p run:2];
p.run(2);
void(^run)() = p.run;
run();
}
上述代碼中[p run:2];
和 p.run(2);
作用是一樣的
若只寫p.run
只是相當于拿到了block,即void(^run)() = p.run;