烦人的小东西 block块

block基本用法

block块 官方名称:闭包,类似于C语言中的匿名函数,通常作为delegate的代替品使用
block的使用和方法(函数)类似,包括声明,实现,调用三个部分 不同的是block的声明和实现可以写在方法内部,下面是声明block方法的几种方式
    void(^test2)(); //如果没有参数 括号可以省略
    NSInteger(^test3)();
    NSInteger(^test4)(NSString * str);
    NSString*(^test5)(NSString * str,BOOL a);
实现方法
    test4 = ^(NSString * str){
        NSLog(@"test4%@",str);
        NSInteger i = 0;
        return i;
    };
block支持声明和实现同时写,把它们写在一起是这样的
    void(^test6)(NSString * text)=^(NSString * text){
        NSLog(@"test=%@",text);
    };
和普通方法一样,如果不对block块进行调用则block永远不会执行,声明是告诉编译器,我这里来了位block兄弟,如果有人找(调用)你不能说你不认识.可如果声明了不实现就调用,就会造成系统崩溃,所以,在调用一个无法确定有没有被实现的block方法时需要增加一个判断:
    //判断方法是否存在 不存在则不调用 防止调用未实现方法引起崩溃
    if (test2) {
        test2();
    }

block的调用和C方法的调用方式相同,

NSInteger i = test5(@"1",YES);

block的作用范围和变量相同,分为局部和全局block,局部block只能在局部里面实现和调用,而全局则可以在任意一个方法体内实现和调用(不可以在方法体外部进行调用和实现,这里和普通方法有所区别).有时候我们需要为多次重复使用的block方法定义一个简单的名称:

    typedef  void(^test)(NSInteger str);
这样以后再次声明void(^test)(NSInteger str)格式的block快时就可以:
    test block1;
这样声明调用的方式不变,不过实现的时候则趋于属性了,他是这样的
    block1 = ^(NSInteger str){
        NSLog(@"%d",str);
    };  

block用法实战

block在实际应用中,主要是用于在不同的类中传递数据,其传递特性是:必须有一方类中包含另一方类的对象,具体使用流程如下(类A 向 类B 传值 改变类B的背景颜色):

    //1.声明一个 block 类型,返回值表明传值的结果,参数表明传值的数据。
    typedef void(^block)(UIColor* color);
    //2.声明一个 block 属性。
    @property (nonatomic, copy) block block;
    //3.调用 block 进行传值。
    if (_block) {
        //调用 block 前需要判断 block 是否实现。
        _block(_colors[sender.selectedSegmentIndex]);
    }
    //4.实现 block 并获取传过来的值。
    vc.block = ^(UIColor* color){
        self.view.backgroundColor = color;
    };

第1 2 3 是类A中的代码4为类B中的代码.

内存管理

block中的内存管理比较复杂,对于block自身的内存管理与其他类型的变量或属性相同,声明为属性时需要用copy,但是block不仅要管理自身的内存.它还会对方法快中使用的外部变量进行引用计数加一,如果使用了本类对象的属性.那么就会对self进行retain,这是非常糟糕的事情,会让你的内存管理变得无从下手,什么时候释放?释放谁?怎么解决self被retain后的循环引用问题?有一个很简单的办法:
//使用__block语句修饰将要在block块中使用的对象
    __block NSArray* array1 = [[NSArray alloc] initWithObjects:@"array1Object", nil];
    //如果是 self,需要这样做,声明新的 __block 修饰的变量等于 self,然后在 block 中使用新的变量代替 self。
    __block ViewController* blockSelf = self;

mark

block中是不允许修改外部变量的值得,如果必须要修改则需要在变量前面添加__block 否则将会失败

还有很多疑问

虽然写了这么多,可看了更多的博客以后发现自己对block的认知越来越模糊了.什么时候使用,怎么正确的使用又成了问题.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值