ios Bloack浅析

1.你可以理解Block是属于一种特殊的函数或者说特殊的方法,或者说Bloack的本质和其他的变量类似,不同的是,代码块存储的数据是一个函数体。使用代码块,你可以像调用其他标准函数一样的调用,可以传入参数,并得到返回值。借图,原文链接见最下面2.Block存储
根据Block在内存中的位置分为三种类型NSGlobalBlock,NSStackBlock, NSMallocBlock。
NSGlobalBlock:类似函数,位于text段;
NSStackBlock:位于栈内存,函数返回后Block将无效;
NSMallocBlock:位于堆内存。

那么区别在哪呢?引用别人的一段代码

   Sum sum1 = ^ long (int a, int b) {
            return a + b ;
        };
        NSLog(@"sum1 = %@", sum1);// 打印结果:sum1 = <__NSGlobalBlock__: 0x47d0>
     
     
     
     
    int base = 100;
    Sum sum2 = ^ long (int a, int b) {
        return base + a + b;
    };
    NSLog(@"sum2 = %@", sum2); // 打印结果:sum2 = <__NSStackBlock__: 0xbfffddf8>
    														ARC模式下会打印__NSMallocBlock__,因为ARC会自动拷贝到堆上
     
     
     
    Sum sum3 = [sum2 copy];
    NSLog(@"sum3 = %@", sum3); // 打印结果:sum3 = <__NSMallocBlock__: 0x902fda0>
    NSLog(@"Hello, World!");

结果很明显了:周围变量没有引用的Block,就是__NSGlobalBlock__。加入了对定义环境变量的引用,就是__NSStackBlock__。,如果你对一个NSStackBlock对象使用了copy,就会得到__NSMallocBlock__。
所以注意此处写法
@property (nonatomic,copy)MyBlock block;
此处应使用copy,因为当我们用copy修饰的时候,系统会把该 block的实现拷贝一份到堆区,就是__NSMallocBlock__。
3.Block中使用外部变量问题
1)系统会把使用到的外部变量通过参数列表传递给block,也就变成了block内部的局部变量
2)而在传递的时候,对于基本数据类型的外部变量来说,系统默认传递的仅仅是值,也就是说这个局部变量是不能修改的。如果想修改值,会使用__block来修饰这个变量。这样一来,系统在传递的时候,传的就是外部变量的地址,这样我们就可以修改值了。
3)对于对象类型,传递的是地址,同时默认对该对象进行了一次强引用(或计数器加一)。系统进行了强引用,而他又对该对象的内存管理袖手旁观,也就是说,它只做了强引用,但是没有做释放操作。这个时候就会造成内存泄漏。所以,我们在使用对象的时候,在MRC下,都会使用__block修饰,在ARC下,使用__weak修饰,这样一来,系统在传递的时候就不会对该对象进行强引用,避免了内存泄漏。
4.类间传值
A类中用了B类 可是在A类中通过B.block = … 的方式快速实现,不用定制协议。
参考文章:
https://www.cnblogs.com/libaoshen/p/5861466.html
https://www.cnblogs.com/liujun5020/p/5643045.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值