小技巧:block的书写格式的快捷方式,可直接敲inlineBlock
,如下图:
一、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;