iOS 学习Block


一、截获自动变量值

     //截获自动变量值
        int val = 132;
        const char *fmt = "val = %d\n";
        
        /*
         在blocks中,block表达式使用的是在它声明之前的自动变量val。
         block表达式截获所使用的自动变量的值,即保存了该自动变量的瞬间值,
         因为block表达式保存了自动变量的值,所以在执行block语法后,即使改变bock中使用的自动变量的值也不会影响block执行时自动变量的值
         所以两次输出的结果是一样的 都是:val = 132
         */
        void (^blk)(void) = ^{
            printf(fmt,val);
        };
        blk();
        val = 12345;
        blk();


二、__block 说明符

//__block说明符
        /*
         实际上,自动变量值截获只能保存在执行block语法瞬间的值,保存后就不能改写该值。
         如果在block中尝试改变截获的自动变量的值,看看会有什么结果
         */
        
        int val = 0;
        void (^blk)(void) = ^{
            val = 1;
        };
        blk();


这个时候就会出现如下图的错误提示啦:




那么该如何解决呢?--------  使用  __block 说明符


 //若想在block语法的表达式中将值赋给在block语法外声明的自动变量,
        //需要在该自动变量的前面附加  __block 说明符,就可以实现在block内赋值。
        __block int val = 0;
        void (^blk)(void) = ^{
            val = 1;
            NSLog(@"val = %d",val);
        };
        blk();

三、截获的自动变量

上面提到,如果将值赋给block中的自动变量,就会产生编译错误。那么对于截获的objective-c对象,调用变更该对象的方法也会产生这样的编译错误吗?

请看下面的例子:

id array = [[NSMutableArray alloc]init];
        void (^blk)() = ^{
            id obj = [[NSObject alloc] init];
            [array addObject:obj];
        };
        blk();

这个是没有问题的,首先,block中截获的是NSMutableArray类对象的结构体实例指针,这里是使用截获的值,所以没有问题,但是如果向截获的变量赋值则会产生编译错误。看看下面的例子:

id array = [[NSMutableArray alloc]init];
        void (^blk)() = ^{
            array = [[NSMutableArray alloc]init];
        };
        blk();

这个时候就会出现编译错误的提示啦!


显然,需要给截获的自动变量附加 __block 说明符才可以解决问题。


四、另外,在使用c语言数组的时候必须小心使用其指针,例如:

const char text[] = "hello world";
        void (^blk)(void) = ^{
            printf("%c \n",text[2]);
        };

这个会出现如下的编译错误:



其实在block中,截获自动变量的方法并没有实现对c语言数组的截获,这时可以使用指针解决这个问题。

上面的代码稍微改动一下就可以了。

const char *text = "hello world";
        void (^blk)(void) = ^{
            printf("%c \n",text[2]);
        };
        blk();

运行时就可以输出  字符:l


五、

Block会保持一个strong指针指向block内被使用的所有对象,即这些被引用的对象会保持在heap中直到block生命周期结束。

MemoryCycle(内存循环)问题:

以下(在控制器类中)定义属性并使用Block 的代码: 

@property(nonatomic ,strong) NSMutableArray *myBlocks;// block array

[self.myBlocksaddObject:^{ //Block可当作对象使用

        [selfdoSomething];

 }];

    由于 Block 内引用了 self,因此self(通过myBlocks 属性) 和 Block 均有 一个strong 指针指向彼此,此时self 及 Block 均无法从内存中释放!

 

解决方法:


定义一个 weak 指针:


__weakMyClass *weakObj = self;

//arrayofblocks

@property(nonatomic,strong)NSArray*myBlocks;

[self.myBlocks addObject:^{

[weakObjdoSomething];

 }];

Block拥有一个指向weakObj 的 weak 指针,self 拥有一个指向 myBlock 的 strong 指针。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值