• __block和__weak修饰符的区别


    • block下循环引用的问题

      • __block本身并不能避免循环引用,避免循环引用需要在block内部把__block修饰的obj置为nil
      • __weak可以避免循环引用,但是其会导致外部对象释放了之后,block 内部也访问不到这个对象的问题,我们可以通过在 block 内部声明一个 __strong
        的变量来指向 weakObj,使外部对象既能在 block 内部保持住,又能避免循环引用的问题
    • __block与__weak功能上的区别。

      • __block会持有该对象,即使超出了该对象的作用域,该对象还是会存在的,直到block对象从堆上销毁;而__weak仅仅是将该对象赋值给weak对象,当该对象销毁时,weak对象将指向nil;
      • __block可以让block修改局部变量,而__weak不能。

    另外,MRC中__block是不会引起retain;但在ARC中__block则会引起retain。所以ARC中应该使用__weak。

    因此,__block和__weak修饰符的区别其实是挺明显的:
    1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
    2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
    3.__block对象可以在block中被重新赋值,__weak不可以。
    4.__block对象在ARC下可能会导致循环引用,非ARC下会避免循环引用,__weak只在ARC下使用,可以避免循环引用。

    作者:知乎用户
    链接:https://www.zhihu.com/question/34593410/answer/59725212
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    首先,block中为什么会用到weakself是因为要避免循环引用,一旦出现循环引用那么对象就会常驻内存。如果一个应用程序里面你有很多循环引用,那么内存占用就会比较大,这当然是谁都不想看到的结果。那么问题的重点就是:什么时候会出现循环引用?先来看一个例子:
    NSArray *anArray = @[@"1", @"2", @"3"];
    [anArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        [self doSomething:idx];
    }];
    

    这种情况下,block中retain了self,当block中的代码被执行完后,self就会被ARC释放。所以不需要处理weakself的情况。

    再来看一个例子:
    @interface aViewController ()
    @property (nonatomic, strong) void(^aBlock)(id obj, NSUInteger idx, BOOL *stop);
    @end
    
    __weak aViewController *weakSelf = self;
    self.aBlock = ^(id obj, NSUInteger idx, BOOL *stop) {
        [weakSelf doSomething:idx];
    }
    

    这个例子的区别在于:block被self strong引用。所以结果就是block中引用了self,self引用了block。那么这个时候,如果你不使用weakself,则self和block永远都不会被释放。

    那么是不是遇到block都要使用weakself呢?当然不是,而且如果全部使用weakself,会出现你想执行block中的代码时,self已经被释放掉了的情况。

    另外,在处理weakself时,有两种做法:__weak和__unsafe_unretained。两种做法各有推荐,有的人觉得后者从字面上更好理解,而有的人觉得前者更加安全,因为self被释放时会自动指向nil。有的人又说了,就是应该让app崩溃才能发现问题所在。这个,看个人吧。
  • 相关阅读:
    javascript的字段值,私有变量,静态方法声明
    取得序列中某个点的范围边界
    使用wubi安装ubuntu11.04后无线网卡被禁用无法打开解决办法
    WEB前端性能优化
    jQuery的arrayLike
    在手机上安装BT5系统,没错就是破解无线密码的那个
    PHP在子类方法B调用父类的方法A时,不传参数时仍能得到方法B的名称
    讨厌的文本选区
    PHP遍历解析XML为一个数组
    “软工厂代码生成工具”的学习笔记
  • 原文地址:https://www.cnblogs.com/sunjianfei/p/6688876.html
Copyright © 2020-2023  润新知