iOS __weak 和 __block 的使用探讨

在基本的开发中遇到 需要弱引用时候 我一般 用 weak  预防 死锁的时候 我会用 block

的确没出过大错  但是这样处理 的确有点囫囵  现在我想好好理解一下这两个修饰符

"block中用到的外部变量最好使用 __weak 修饰,避免内存泄露; block容易引起引用循环的根本原因是: 1,对于(block内部用到的)外部变量,对其执行retain 的时机 与该block的执行时机是不同步的,在block声明的时候就对外部变量进行了retain,而block何时执行甚至是否执行都是不可预测的; 2,block 一般是匿名的,而且copy赋值的,手动释放block对象比较困难"

我理解的意思是 在使用闭包 时候建议 外部变量 使用 __weak 弱引用来修饰   有两个要点如下:

1.若附有__weak 修饰符的变量所引用的对象被废弃,则将nil 赋值给该变量

下边的代码就可以解释成 当 self.helperView 被废弃的时候 helperView 为nil

self.helperView = [[LittleHelperView alloc]init];//__weak helperView所引用的对象 self.helperView
        __weak LittleHelperView *helperView = self.helperView;//__weak 修饰的变量 helperView
        helperView.tapBlock = ^(LittleHelperActionType actionType,__weak HelperListAction * _Nonnull  helperAction){
            [self golittleHelperViewAction:actionType andAction:helperAction];
        };

2. 使用附有__weak 修饰符的变量,即是使用注册到autoreleasepool 中的对象

我的理解就是 操作  __weak LittleHelperView *helperView  就是在操作  self.helperView 就是说 操作弱引用 就是间接操作弱引用对象

由于最开始生成并持有的对象为附有__strong修饰符变量self.helperView所持有的强引用,所以在该变量作用域结束之前都始终存在。因此如下所示,在变量作用域结束之前,可以持续使用附有__weak修饰符的变量helperView所引用的对象。

其实这两条 大概表述的是 一个意思

网上 一篇文章很受用  分享给大家 http://my.oschina.net/u/255456/blog/423991

__block比使用__weak修饰符的好处是可以更改变量的值   __weak 只是引用 __block 可修改 引用对象的值

也就是说在Block使用中,Block内部能够读取外部局部变量的值。但需要改变这个变量的值时,我们需要给它附加上__block修饰符。

__block另外一个比较多的使用场景是,为了避免某些情况下Block循环引用的问题,我们也可以给相应对象加上__block 修饰符

所以 才说 上面橘色的那句

参考 http://chun.tips/blog/2014/11/13/hei-mu-bei-hou-de-blockxiu-shi-fu/

使用场景 模拟  __block避免循环引用

如果你引用的是一个实例变量,它会直接对self进行retain,这有时候有可能会产生一个引用环(两个或以上的对象之间直接或间接地互相引用)并导致内存泄露。解决的方法是:当需要在Block中访问实例变量的时候,创建一个指向self的指针,并对其使用__block修饰符,这样self不会被自动retain: 

- (void)foo {
    __block id blockSelf = self;
    ^ {
        blockSelf->bar = 3;
    }
}

参考 http://m.blog.csdn.net/blog/shishuio/8468423

时间: 2024-10-15 22:38:26

iOS __weak 和 __block 的使用探讨的相关文章

__weak 和 __block 区别

Blocks理解: Blocks可以访问局部变量,但是不能修改 如果修改局部变量,需要加__block __block int multiplier = 7; int (^myBlock)(int) = ^(int num) { multiplier ++;//这样就可以了 return num * multiplier; }; 2.如果局部变量是数组或者指针的时候只复制这个指针,两个指针指向同一个地址,block只修改指针上的内容.如: NSMutableArray *mArray = [NS

iOS 8:__weak与__block

关键字:ARC __weak  __block 1.__weak不增加引用,__block增加引用.举例:对象内有一个强引用的block成员变量,此成员变量又强引用该对象,若对象不经过__weak处理,则二者循环引用. 2.若block需要改变局部变量的值,则局部变量需要用__block修饰. 参考: http://www.cocoachina.com/bbs/3g/read.php?tid=258850

__weak与__block修饰符区别

API Reference对__block变量修饰符的解释,大概意思: 1.__block对象在block中是可以被修改.重新赋值的. 2.__block对象在block中不会被block强引用一次,从而不会出现循环引用问题. API Reference对__weak变量修饰符的解释,大概意思: 使用了__weak修饰符的对象,作用等同于定义为weak的property.自然不会导致循环引用问题,因为苹果文档已经说的很清楚,当原对象没有任何强引用的时候,弱引用指针也会被设置为nil. 因此,__

What the difference between __weak and __block reference?

近日遇到一个非常细的知识点,关于block的循环引用问题.相比非常多人都遇到了.也能顺利攻克了,至于block方面的技术文章.那就很多其它了.这里不再赘述,可是有这样一个问题: 使用场景: __block typeof(self) tmpSelf = self; [self methodThatTakesABlock:^ { [tmpSelf doSomething]; }]; 那么这样写: __block typeof(self) tmpSelf = self; 和 __weak typeof

__weak与__block修饰符到底有什么区别

API Reference对__block变量修饰符有如下几处解释: //A powerful feature of blocks is that they can modify variables in the same lexical scope. You signal that a block can modify a variable using the __block storage type modifier. //At function level are __block vari

__weak与__block区别

__weak 本身是可以避免循环引用的问题的,但是其会导致外部对象释放了之后,block 内部也访问不到这个对象的问题,我们可以通过在 block 内部声明一个 __strong 的变量来指向 weakObj,使外部对象既能在 block 内部保持住,又能避免循环引用的问题 __block 本身无法避免循环引用的问题,但是我们可以通过在 block 内部手动把 blockObj 赋值为 nil 的方式来避免循环引用的问题.另外一点就是 __block 修饰的变量在 block 内外都是唯一的,要

IOS中的__block关键字简单使用

/**13.__block什么时候用?**/ 结论:在block里面修改局部变量的值都要用__block修饰 /**14.请教一个问题:在block里面, 对数组执行添加操作, 这个数组需要声明成 __block吗?**/ 不需要声明成__block,因为testArr数组的指针并没有变(往数组里面添加对象,指针是没变的,只是指针指向的内存里面的内容变了) /**15.在block里面, 对NSInteger进行修改, 这个NSInteger是否需要声明成__blcok ?**/ NSInteg

iOS __weak __strong

在block中常常会用到self,可是会造成循环引用.这时候就需要这样来解决这个问题: #define WeakSelf __weak __typeof(self) weakSelf = self #define StrongSelf __strong __typeof(weakSelf) self = weakSelf - (void)aFunc:(id)sender { WeakSelf;//1 [UIView animateWithDuration:1 animations:^{ Stro

iOS __weak学习碰到的疑问

__weak弱引用并不持有对象,所以赋值给__weak修饰符的变量也不会改变计数器的值. main.m id __strong obj3 = nil; id __weak obj1= nil; /* id __weak obj1 = obj; 编译器的模拟代码如下: id obj1; objc_iniitWeak(&obj1,obj); objc_destroyWeak(&obj1); */ @autoreleasepool { id obj = [[NSObject alloc] ini