iOS block详解

99封情书 提交于 2020-03-08 18:49:04

概述

在这里插入图片描述

Block的定义与使用

//1.无参数,无返回值,声明和定义
    void(^MyBlockOne)(void)=^(void){
        NSLog(@"无参数,无返回值");
    };
    MyBlockOne();//block的调用
//2.有参数,无返回值,声明和定义
    void (^MyblockTwo)(int a)=^(int a){
        NSLog(@"a=%d我就是block,有参数,无返回值",a);
    };
    MyblockTwo(100);
//3.有参数,有返回值
    int(^MyBlockThree)(int,int)=^(int a,int b){
        NSLog(@"%d我就是block,有参数,有返回值",a+b);
        return a+b;
    };
    NSLog(@"%@",MyBlockThree);
    NSLog(@"%d",MyBlockThree(12,1));

注意打印block用%@,打印调用block的结果,要用具体类型,如%d

//4.无参数,有返回值
    int (^MyBlockFour)(void)=^{
        NSLog(@"无参数,有返回值");
        return 45;
    };
    NSLog(@"%d",MyBlockFour());

实际开发中的定义

例如,用typedef 定义一个block;

typedef int (^MyBlock)(int,int);

这时,MyBlock就成为了一种Block类型在定义类的属性时可以这样:

@property (nonatomic,copy)MyBlock myBlock;

使用时:

//实际使用
    self.myBlock = ^int(int a, int b) {
        NSLog(@"实际使用");
        return a+b;
    };
    NSLog(@"%d",self.myBlock(1,3));

block与外界变量

截获自动变量(局部变量)值

默认情况

在这里插入图片描述

int age=10;
    myBlock block=^{
        NSLog(@"age=%d",age);
    };
    age=18;
    block();

输出结果:

age=10

__block修饰的外部变量

在这里插入图片描述

//__block修饰的外部变量
    __block int ageOne=10;
    myBlock blockOne=^{
        NSLog(@"ageOne=%d",ageOne);
    };
    ageOne=18;
    blockOne();

输出为:

ageOne=18

为什么__block修饰的外部变量的值就可以被block修改呢?
在这里插入图片描述

Block的copy操作

Block的存储域及copy操作

在这里插入图片描述
在这里插入图片描述
遇到一个Block,我们如何知道这个Block的存储位置呢?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

__block变量与__forwarding

在这里插入图片描述

防止Block循环引用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Block的使用示例

Block作为变量(Xcode快捷键:inlineBlock)

在这里插入图片描述

Block作为属性(Xcode快捷键:typedefBlock)

在这里插入图片描述

作为OC中的方法参数

//---无参数传递的Block---
//实现
-(CGFloat)testTimeConsume:(void(^)(void))middleBlock{
    //执行前记录下当前的时间
    CFTimeInterval startime=CACurrentMediaTime();
    middleBlock();//这里调用block参数
    //执行后记录下当前的时间
    CFTimeInterval endTime=CACurrentMediaTime();
    return endTime-startime;
}

//---无参数传递的Block---调用
 [self testTimeConsume:^{
     //放入block中的代码
     NSLog(@"---无参数传递的Block---调用");
  }];



//---有参数传递的Block---
//实现
-(CGFloat)testTimeConsumeOne:(void(^)(NSString *name))middleBlock{
     //执行前记录下当前的时间
    CFTimeInterval startime=CACurrentMediaTime();
    NSString *name=@"有参数";
    middleBlock(name);
    //执行后记录下当前的时间
    CFTimeInterval endTime=CACurrentMediaTime();
    return endTime-startime;
}

//---有参数传递的Block---调用
    [self testTimeConsumeOne:^(NSString *name) {
        //放入block中的代码,可以使用参数name
        //参数name是实现代码中传入的,在调用时只能使用,不能传值
        NSLog(@"%@",name);
    }];

block回调

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
demo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!