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);
    };
}