block的注意事项,在之前的博客里说明过,面试有经常能遇到,但是呢,实际中怎么用,有些盆友,还是用的晕晕乎乎,下面说一下block的用法,希望能帮到大家.
一、Block的声明、定义和调用
1)、声明 与 定义
打开
Xcode
,二话不说:输入
inline…
估计都不用输入完就可以看到这个:
接着回车就可以看到下面的内容:
这里block的每一个参数就很详细了,返回值,block名称,参数列表.
左边是block的声明,右边则是block的定义
- returnType:block 的返回类型
- blockName:block 的名字
- parameterTypes:block的参数
如果是一个没有返回值,没有参数的简单block,就是
void(^myBlock)() = ^() {
NSLog(@"执行block");
};
2)、 block调用
那么:Block的调用呢?block名称加个小括号即可
blockName();
3)、分开写出来
//1.声明 类型:void(^ )() 名:blockName
void(^blockName)();
//2.定义
blockName = ^() {
NSLog(@"执行block");
};
//3.执行
blockName();
4)、根据上面可以总结出:
block:一个匿名的代码块
block作用:帮你保存一份代码,等到恰到的时候去调用
二、Block的几种使用场景
(一)、应用场景1:把block保存到对象里。调用:在恰当的时候调用
@interface Person : NSObject
//在对象里声明一个block
@property (nonatomic, copy) void(^myBlock)();
@end
//声明定义一个 block 代码块 别忘了inlineBlock
void(^myBlock)() = ^() {
NSLog(@"11111");
};
Person *p = [[Person alloc] init];
//保存到对象里
p.myBlock = myBlock;
//调用block
p.myBlock();
(二)、应用场景2:应用场景2:把block当做方法的参数使用,调用:外界不调用,都是方法内部调用
注意:
- (void)eat:(void(^myBlock)())myBlock; 这样会报错;
解决:block名字只能为一个,在中间或者后面,(部分盆友经常会犯错)
正确例如:
@property (nonatomic, copy) void(^blockName)(); block名字在中间
-(void)eat:(void(^)())blockName; block名字在后面
方法声明:
-(void)eat:(void(^)())myBlock;
实现:
-(void)eat:(void(^)())myBlock{
//把block当做参数,在方法内部执行
myBlock();
}
(三)、重点补充:类型的别名,特别重要
用处:1.控制器之间传值;2.方法回调
位置:在 @interface 类名 上面
正常block作为参数的方法如下:
- (void)eat:(void(^)())myBlock;
通过“类型的别名”做之后呢,分成两部:
第一步:
//typedef <#returnType#>(^<#name#>)(<#arguments#>);
typedef void(^SuccessBlock)();
# void(^)() == SuccessBlock:这是类型哦
第二步:
-(void)eat:(SuccessBlock)myBlock;
-(void)eat:(SuccessBlock)myBlock{
myBlock();
}
(四)、应用场景3:把block当做方法的返回参数使用,外界不调用,都是方法内部去调用
Person *person = [[Person alloc] init];
person调方法是这样的:[person run];
如果想通过 person.run,怎么做呢??
这个在一些masonry和RAC中经常见到,素以要重视起来;
其实:
person.run 返回类型是一个block,
//()里面就是返回类型啊
-(void(^)())run;
-(void (^)())run{
return ^() {
NSLog(@"block的内容");
};
}
person.run();
/ * 解析 person.run():
*
* person.run 其实是一个block,是一个返回的block,例如:可以用myBlock接收
* 然后() :执行block
*
// void(^myBlock)() = person.run;
//
// myBlock();
*/
那么如果?再多加个传参数呢?例如:person.run(3):
解析:
如果传个参数呢 ,从myBlockRunning(3)开始,回倒
void(^myBlockRunning)(int metre) = person.running;
myBlockRunning(3);
//总之:理解了整个过程,以后用这个就OK
person.running(3);
-(void(^)(int))running{
return ^(int metre) {
NSLog(@"block的内容--%d米",metre);
};
}