一、block基本用法
基本构成: (返回值)(^block名)(参数) = ^(参数){ 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作为属性传值
(返回值)(^名称)(参数)
@property(nonatomic, copy) void(^myBlock) (NSString * text);
block属性传值用在下一个界面的值需要往上一个页面传的情况
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用于回调,当ControllerA向ControllerB Push的时候,并没有调用
myBlock(),而是在ControllerB向ContollerA Pop的时候才调用,给
textField.text 赋值
三、block作为函数参数
情形描述:
//1.我在玩手机
//2.手机没电了
//3.我在看电视
//4.电充好了
//5.我继续玩手机
NSLog(@"我在玩手机");
NSLog(@"手机没电了");
NSLog(@"我在看电视");
NSLog(@"电充好了");
NSLog(@"我继续玩手机”);
输出结果:
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] 我继续玩手机
但是,电充好 不可能瞬时完成,所以考虑延时3秒
NSLog(@"我在玩手机");
NSLog(@"手机没电了");
NSLog(@"我在看电视");
[self performSelector:@selector(chargeFinish) withObject:nil afterDelay:3];
NSLog(@"我继续玩手机");
- (void)chargeFinish{
NSLog(@"电充好了");
}
输出结果:
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] 我继续玩手机
2016-06-01 16:01:19.842 DataSave[18427:1356201] 电充好了
输出结果中,电充好了 在最后出现,不合理,应该是电充好了再继续玩手机
考虑另外一种办法
NSLog(@"我在玩手机");
NSLog(@"手机没电了");
NSLog(@"我在看电视");
[self performSelector:@selector(chargeFinish) withObject:nil afterDelay:3];
- (void)chargeFinish{
NSLog(@"电充好了");
NSLog(@"我继续玩手机");
}
输出结果:
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] 我继续玩手机
这样看功能是达到了,但是我第二天不想继续玩手机,想在电充好之后去逛街,这样
就得修改方法内部;此时,考虑把第二天想做的事情当作参数传入函数是最为恰当的
NSLog(@"我在玩手机");
NSLog(@"手机没电了");
[self chargeMyIphone:^{
NSLog(@"继续玩手机");
}];
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作为参数传递到函数内部格式:
(返回值(^)(参数))(block名),这样只需要以参数的形式传入就好。
block用copy修饰
block里不能改变block外面的变量,如果需要改变必须在变量前面加__block 修饰符
block里面要用weakself,但是在调用方法的时候又要把weak变成strong
网友评论