烦人的小东西 block块

来源:互联网 发布:电信4g卡显示3g网络 编辑:程序博客网 时间:2024/05/20 17:09

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