一、block基本用法
基本構(gòu)成: (返回值)(^block名)(參數(shù)) = ^(參數(shù)){ block實體 };
1.無參無返回值的Block
void(^printBlock)() = ^(){
NSLog(@"myBlock");
};
printBlock();
2.有參無返回值的Block
void(^printBlock)(int, int) = ^(int a, int b){
NSLog(@"the sum of a + b = %d",a + b);
};
printBlock(5 , 10);
3.有參有返回值
int (^printBlock)(int, int) = ^(int a, int b){
return a + b;
};
int sum = printBlock(5 , 10);
二、block作為屬性傳值
(返回值)(^名稱)(參數(shù))
@property(nonatomic, copy) void(^myBlock) (NSString * text);
block屬性傳值用在下一個界面的值需要往上一個頁面?zhèn)鞯那闆r
Controller A 里有ButtonA,textFieldA,給ButtonA添加事件是:點擊push到
ControllerB,在ControllerB中有ButtonB,textFieldB,給ButtonB添加的事
件是點擊pop回ControllerA,同時把textFieldB里面的text傳到textFieldA里
在ControllerA中代碼
- (IBAction)push:(id)sender {
NextViewController * next = [[NextViewController alloc] init];
next.myBlock = ^(NSString *text){
self.textField.text = text;
};
[self presentViewController:next animated:YES completion:^{
NSLog(@"12312");
NSLog(@"%s",__func__);
}];
// [self presentViewController:next animated:YES completion:nil];
}
在ControllerB中的.h文件中定義block
@property(nonatomic, copy) void(^myBlock) (NSString * text);
在ControllerB的.m文件中:
- (void)pop{
if (self.myBlock) {
self.myBlock(@"123");
}
[self dismissViewControllerAnimated:YES completion:nil];
}
block用于回調(diào),當ControllerA向ControllerB Push的時候,并沒有調(diào)用
myBlock(),而是在ControllerB向ContollerA Pop的時候才調(diào)用,給
textField.text 賦值
三、block作為函數(shù)參數(shù)
情形描述:
//1.我在玩手機
//2.手機沒電了
//3.我在看電視
//4.電充好了
//5.我繼續(xù)玩手機
NSLog(@"我在玩手機");
NSLog(@"手機沒電了");
NSLog(@"我在看電視");
NSLog(@"電充好了");
NSLog(@"我繼續(xù)玩手機”);
輸出結(jié)果:
2016-06-01 15:57:59.215 DataSave[18394:1354084] 我在玩手機
2016-06-01 15:57:59.216 DataSave[18394:1354084] 手機沒電了
2016-06-01 15:57:59.216 DataSave[18394:1354084] 我在看電視
2016-06-01 15:57:59.216 DataSave[18394:1354084] 電充好了
2016-06-01 15:57:59.216 DataSave[18394:1354084] 我繼續(xù)玩手機
但是,電充好 不可能瞬時完成,所以考慮延時3秒
NSLog(@"我在玩手機");
NSLog(@"手機沒電了");
NSLog(@"我在看電視");
[self performSelector:@selector(chargeFinish) withObject:nil afterDelay:3];
NSLog(@"我繼續(xù)玩手機");
- (void)chargeFinish{
NSLog(@"電充好了");
}
輸出結(jié)果:
2016-06-01 16:01:16.839 DataSave[18427:1356201] 我在玩手機
2016-06-01 16:01:16.839 DataSave[18427:1356201] 手機沒電了
2016-06-01 16:01:16.839 DataSave[18427:1356201] 我在看電視
2016-06-01 16:01:16.839 DataSave[18427:1356201] 我繼續(xù)玩手機
2016-06-01 16:01:19.842 DataSave[18427:1356201] 電充好了
輸出結(jié)果中,電充好了 在最后出現(xiàn),不合理,應該是電充好了再繼續(xù)玩手機
考慮另外一種辦法
NSLog(@"我在玩手機");
NSLog(@"手機沒電了");
NSLog(@"我在看電視");
[self performSelector:@selector(chargeFinish) withObject:nil afterDelay:3];
- (void)chargeFinish{
NSLog(@"電充好了");
NSLog(@"我繼續(xù)玩手機");
}
輸出結(jié)果:
2016-06-01 16:02:55.953 DataSave[18453:1357152] 我在玩手機
2016-06-01 16:02:55.954 DataSave[18453:1357152] 手機沒電了
2016-06-01 16:02:55.954 DataSave[18453:1357152] 我在看電視
2016-06-01 16:02:58.954 DataSave[18453:1357152] 電充好了
2016-06-01 16:02:58.955 DataSave[18453:1357152] 我繼續(xù)玩手機
這樣看功能是達到了,但是我第二天不想繼續(xù)玩手機,想在電充好之后去逛街,這樣
就得修改方法內(nèi)部;此時,考慮把第二天想做的事情當作參數(shù)傳入函數(shù)是最為恰當?shù)?
NSLog(@"我在玩手機");
NSLog(@"手機沒電了");
[self chargeMyIphone:^{
NSLog(@"繼續(xù)玩手機");
}];
NSLog(@"我在看電視”);
- (void)chargeMyIphone:(void(^)(void))finishBlock{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"電充好了");
finishBlock();
});
}
將block作為參數(shù)傳遞到函數(shù)內(nèi)部格式:
(返回值(^)(參數(shù)))(block名),這樣只需要以參數(shù)的形式傳入就好。
block用copy修飾
block里不能改變block外面的變量,如果需要改變必須在變量前面加__block 修飾符
block里面要用weakself,但是在調(diào)用方法的時候又要把weak變成strong