博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS block分析
阅读量:7056 次
发布时间:2019-06-28

本文共 3400 字,大约阅读时间需要 11 分钟。

block是代码块,其本质和变量类似。不同的是代码块存储的数据是一个函数体。使用Block,就可以像其他标准函数一样,传入参数,并得到返回值。

可以把Block当做Objective-C的匿名函数,Block允许开发者在两个对象之间将任意的语句当做数据进行传递,block的实现具有封闭性(closure),而又能够很容易获取上下文的相关状态信息。 

 

Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等。

ARC情况下

  1.如果用copy修饰Block,该Block就会存储在堆空间。则会对Block的内部对象进行强引用,导致循环引用。内存无法释放。

解决方法:

  新建一个指针(__weak typeof(Target) weakTarget = Target )指向Block代码块里的对象,然后用weakTarget进行操作。就可以解决循环引用问题。

  2.如果用weak修饰Block,该Block就会存放在栈空间。不会出现循环引用问题。

MRC情况下

  用copy修饰后,如果要在Block内部使用对象,则需要进行(__block typeof(Target) blockTarget = Target )处理。在Block里面用blockTarget进行操作。

  默认情况下,Block内部不能修改外面的局部变量。

  Block内部可以修改使用__block修饰的局部变量。

1、无参数无返回值的Block

/**     *  void :就是无返回值     *  emptyBlock:就是该block的名字     *  ():这里相当于放参数。由于这里是无参数,所以就什么都不写     */    void (^emptyBlock)() = ^(){        NSLog(@"无参数,无返回值的Block");    };    emptyBlock();

2、有参数无返回值的Block

/**     *  调用这个block进行两个参数相加     *     *  @param int 参数A     *  @param int 参数B     *     *  @return 无返回值     */    void (^sumBlock)(int ,int ) = ^(int a,int b){        NSLog(@"%d + %d = %d",a,b,a+b);    };    /**     *  调用这个sumBlock的Block,得到的结果是20     */    sumBlock(10,10);

3、有参数有返回值的Block

/**     *  有参数有返回值     *     *  @param NSString 字符串1     *  @param NSString 字符串2     *     *  @return 返回拼接好的字符串3     */        NSString* (^logBlock)(NSString *,NSString *) = ^(NSString * str1,NSString *str2){        return [NSString stringWithFormat:@"%@%@",str1,str2];    };    //调用logBlock,输出的是 我是Block    NSLog(@"%@", logBlock(@"我是",@"Block"));
Block结合typedef使用

自己定义一个Block类型,用定义的类型去创建Block,更加简单便捷。

/** *  定义了一个changeColor的Block。这个changeColor必须带一个参数,这个参数的类型必须为id类型的 *  无返回值 *  @param id */typedef void(^changeColor)(id);/** *  用上面定义的changeColor声明一个Block,声明的这个Block必须遵守声明的要求。 */@property (nonatomic, copy) changeColor backgroundColor;
-(void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event{ //声明一个颜色 UIColor *color = [UIColor redColor]; //用刚刚声明的那个Block去回调修改上一界面的背景色 self.backgroundColor(color);}
-(void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event{ ViewController2 *vc =[[ViewController2 alloc]init]; // 回调修改颜色 vc.backgroundColor = ^(UIColor *color){ self.view.backgroundColor = color; }; [self.navigationController pushViewController:vc animated:YES];}

 

iOS-block三种应用场景

  • 1.把block保存成对象中的属性,在恰当的时刻调用

2.把block当成方法的参数使用,block的调用在是在方法内部,在外界写block的实现(最常用)

3.把block当成方法的返回值(比较少用)

示例1

1.在Person类中

@interface Person : NSObject@property (nonatomic,strong) void(^myBlock)(int,int);@end

2.在ViewController类中

- (void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event{ int a = 12; int b = 11; Person *p = [[Person alloc] init]; p.myBlock(a,b);}

示例2

1.在Person类中

@interface Person : NSObject- (void)eat:(void(^)())block;@end@implementation Person- (void)eat:(void (^)())block{    block();}@end

2.在ViewController类中

- (void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event{ // 方式1.先定义,在赋值 // void(^block)() = ^() { // NSLog(@"吃东西"); // }; // // [p eat:block]; // 方式2.直接写block [p eat:^{ NSLog(@"吃东西"); }];}

示例3

1.在Person类中

@interface Person : NSObject- (void(^)(int))run;@end@implementation Person- (void (^)(int))run{    return ^(int b){        NSLog(@"跑了--%d米",b);    };}@end

2.在ViewController类中

- (void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event{ p.run(5);}

 

转载地址:http://eygol.baihongyu.com/

你可能感兴趣的文章
myEclipse新建jsp,默认编码
查看>>
树的prufer编码
查看>>
Python并发编程之线程池&进程池
查看>>
2016/11/19 CSS
查看>>
不要再熬夜了,这是全球公认最健康的作息时间表!
查看>>
用绑定服务来实现放歌的功能
查看>>
bzoj3551 3545
查看>>
hdu5794
查看>>
烂泥:CentOS命令学习之scp复制
查看>>
烂泥:学习ssh之ssh密钥随身携带
查看>>
烂泥:haproxy学习之https配置
查看>>
Spark中map与flatMap
查看>>
mysql 如何优化left join
查看>>
R语言hash
查看>>
深入浅出Mybatis系列(二)---配置简介(mybatis源码篇)
查看>>
字母重排
查看>>
a标签4个伪类的顺序排列
查看>>
css属性
查看>>
excel表格 函数功能
查看>>
js-数组
查看>>