• 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崩溃才能发现问题所在。这个,看个人吧。

__block和__weak修饰符的区别的更多相关文章

  1. __weak 修饰符

    在 HAL 库中,很多回调函数前面使用__weak 修饰符,这里我们有必要给大家讲解__weak 修饰符的作用. weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一 ...

  2. Nullable<T>、Nullable、null、?修饰符的区别

    这章我们讨论一下Nullable<T>.Nullable.null.?修饰符的区别 原创文章 Nullable<T>的前世今生 讨论它们之前,我们有必要讨论一下Nullable ...

  3. __weak修饰符

    前言 在 HAL 库中,很多回调函数前面使用__weak 修饰符. weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”. 加上了__weak ...

  4. iOS中copy和strong修饰符的区别

    iOS中copy和strong修饰符的区别 //用copys修饰的生成的都是不可变的对象 ,如果调用可变类型方法的直接报错 @property(nonatomic,copy)NSString * cp ...

  5. java-权限修饰符的区别

    说明:所谓访问权限,是指对象是否可以通过“.”运算符操作自己的变量或通过“.”运算符使用类中的方法. 1.Java中的四种访问修饰符:public.protected.default(无修饰符,默认) ...

  6. private/默认/protected/public权限修饰符的区别

    private/默认/protected/public权限修饰符和面向对象的三大特性的封装性有着密切关系.它们都可以修饰类的成员,其中的默认和public还可以修饰类. 类的成员包括:成员变量.成员方 ...

  7. Java 语言的类、属性、方法各有哪些修饰符?简述各修饰符的区别

    1. 类的修饰符分为:可访问控制符和非访问控制符两种. 可访问控制符是:公共类修饰符 public 非访问控制符有:抽象类修饰符 abstract :最终类修饰符 final 1.公共类修饰符 pub ...

  8. C#中override和new修饰符的区别

    (new)“隐藏”,(override)“覆盖”(重写).不过要弄清楚这两个有什么区别确实也很难,因为子类在使用父类方法时根本看不出区别,子类不管父类是new了还是override了,用的都是父类方法 ...

  9. java成员变量与局部变量修饰符的区别

    成员变量: 可以被 public,static ,protected,default,final修饰. 局部变量:包括方法里的和 代码块里的(静态和非静态) 可以被default, final修饰 参 ...

随机推荐

  1. onsrcoll和scrollTop兼容与实现

    对于onscroll事件的支持 各浏览器 document.document.body.document.documentElement 对象的 onscroll 事件的支持存在差异. 所谓的支持性存 ...

  2. Android应用安全防护和逆向分析 ——apk反编译

    概述 最近一直在学习Android应用安全相关和逆向分析的知识.现在移动app在安全方面是越来越重视了,特别是那些巨头企业涉及到钱的应用,那加密程度,简直是丧心病狂,密密麻麻.从这里可以看出,对于应用 ...

  3. POST 400 (BAD REQUEST)

    遇到这种错,1,F12打开控制台,2,点击network,找到发送的请求. 3,点击请求,4,看右侧的 Header Preview Response 应该能找到原因. 就拿刚才来说,找了好几个小时原 ...

  4. 如何使不同时区的时间与京8区一致?(JS实现)

    如何使不同时区的时间与京8区一致?(JS实现) Update:2019/1/28 更简单的是使用这个函数(toDate): // 自定义日期格式如下(年月日都必须提供): // "2011- ...

  5. 为 Apache 配置 UTF-8 中文编码

    为 Apache 配置 UTF-8 中文编码 cat /etc/httpd/conf/httpd.conf | grep -n utf -C2 30-# 31-ServerRoot "/et ...

  6. 远程连接MySQL提示 Host is not allowed to connect to this MySQL server

    进入连接的主机修改系统数据库MySQL 下面的user表,把User= root(这里可能是其他你所需要连接的用户名)的这行数据的Host从localhost改为% 如下图: 修改完之后一定要重启My ...

  7. openerp学习笔记 视图(tree\form)中隐藏按钮( 创建、编辑、删除 ),tree视图中启用编辑

    视图(tree\form)中隐藏按钮( 创建.编辑.删除 )create="false" edit="false" delete="false&quo ...

  8. 使用Intent在活动之间穿梭

    使用Intent在活动之间穿梭 1.在com.example.activitytest中创建第二个活动SecondActivity: /** * 第二个活动 */ public class Secon ...

  9. Java的Signature签名转换成.Net

    Java: Signature sig = Signature.getInstance("SHA1withRSA"); sig.initSign(rsaPrivateKey); s ...

  10. PlanetTogether APS安装与配置

    一.PT 安装 1.PT Server与Client的下载 下载网址:https://download.planettogether.com/ 2.安装.net framework 4.6.2 安装P ...