block的使用细节

Block在类中的使用:

1.block在类中作为参数

                              返回类型

-(void)gotoSchool:(void (^)(NSString *name))myBlock;

                                              参数                     block名称

指向一个函数栈空间


2.在类中声明为属性                           形参

 @property(copy) void (^myBlock)(NSString *name);

     ^为block标志                         myBlock为block的名称   



Block 属性的声明,首先需要使用copy修饰,只有copy后的block才会放在堆中,栈中的Block生命周期是和栈绑定的,栈中变量的生命周期是由系统决定的。

      

       另一个需要注意的问题是关于线程安全,在声明Block属性时,需要确认再调用Block时另一个线程有没有可能去修改Block?”。如果确定不会有这种情况的发生,那么Block属性就可以使用nonatomic来修饰,如果不确定的话(一般都是这种情况),那么你首先需要声明Block属性为atomic,也就是保证变量的原子性

      

        atomic :在多线程环境下,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题

        

        nonatomic:如果该对象无需考虑多线程的话,我们可以使用这个属性,这样是编译器少生成一些互斥加锁代码,这样可以提高效率

      

        atomic objc使用的一种多线程保护技术,主要是防止在写入数据未完成时,被其他线程读取数据,造成数据错误,这种机制是非常浪费系统资源的,一般在手机设备上,如果没有用多线程间的通讯编程,我们可以使用nonatomic来提高系统效率。

      

        例如,我们先定义一个Block

        typedef void (^MyBlockType)(NSString name);

        接着使用Block声明一个属性,系统默认是atomic属性

        @property(copy) MyBlockType myBlock;

      

      虽然有了atomic来保证属性的原子性,但是还没有达到线程安全,再调用时,我们先把block赋值给本地变量,防止Block突然改变,如果不这样做的话,即使我们判断了Block属性不为空,在调用之前,如果另一个线程突然把block属性设置为空,那么就会造成程序的crash

          代码如下:

      

      

      

         //  不完善代码,可能会造成crash

         if(self.myBlock)

          {

             //在这里 self.myBlock可能被另一个线程设置为空,这样就会造成crashatomic只会确保myBlock的原子性,这种操作本身还是非线程安全的。

             self.myBlock("哈哈");

          }

          

          // 正确的代码

           MyBlock block=self.myBlock;

           if(block){

                block("哈哈")

            }

      

           MRC

            MyBlock block=[self.myBlock retain];

            if(block){

                block("哈哈")

            }

            [block release];

            在这里如果不使用retain的话,block就不具备持有self.myBlock对象,如果self.myBlock被设置为空,就有可能使block变成野指针。

      

           关于循环引用问题

           ARC下,在调用Block时,我们要使用__weak来修饰self,只有这样我们才可以解决循环引用的问题。

          使用 __weak修饰的指针,在使用后系统自动给它赋值为nil

      

          //iOS 5之前可以用__unsafe_unretained

            //__unsafe_unretained typeof(self) weakSelf = self;


           __weak typeof (self) weakSelf=self;

           self.myblock_1:^(NSString *) {

             [weakSelf run];

           };

      

          在非ARC 显然我们不能使用弱引用,这里我们直接使用block 来修饰,记住在这里使用block不会造成循环引用。

      __block typeof (self) weakSelf=self;

      self.myBlock:^(NSString *){

      [weakSelf run];

      }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值