如何避免在Block里用self造成循环引用

一般来说我们总会在设置Block之后,在合适的时间回调Block,而不希望回调Block的时候Block已经被释放了,所以我们需要对Block进行copy,copy到堆中,以便后用。

当一个Block被Copy的时候,如果你在Block里进行了一些调用,那么将会有一个强引用指向这些调用方法的调用者,有两个规则:

  • 如果你是通过引用来访问一个实例变量,那么将强引用至self
  • 如果你是通过值来访问一个实例变量,那么将直接强引用至这个“值”变量

苹果官方文档里有两个例子来说明这两种情况:

上面第一种情况相当于用self.xxx来访问实例变量,所以强引用指向了self;第二种情况把实例变量变成了本地临时变量,强引用将直接指向这个本地的临时变量。大多数情况下,我们只用处理第一种情况就行了,因为第二种情况虽然会造成循环引用,但是临时变量很快就被释放了,不会造成真正的循环引用。要避免强引用到self的话,用__weak把self重新引用一下就行了,像这样:

[objc] view
plain
copyprint?

  1. __weak ViewController *weakSelf = self;  
时间: 2024-09-14 00:59:23

如何避免在Block里用self造成循环引用的相关文章

ARC下的block导致的循环引用问题解析

ARC下的block导致的循环引用问题解析 更详细细节请参考 http://blog.sina.com.cn/s/blog_8c87ba3b0101m599.html   ARC下,copy到堆上的block,会强引用进入到该block中的外部变量.这很容易导致循环引用的问题. 比方说: 一个VC(这里指一个controller)中有一个属性为model.VC强引用了它. VC --> model 这个model呢,里面有一个copy属性的block,该block赋值如下如下.model.dem

block使用小结、在arc中使用block、如何防止循环引用(zz)

标签:  __block   __weak   arc   self   cfgetretaincount 分类: iOS zz from http://www.cnbluebox.com/?p=255 引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题: [小测试]你真的知道blocks在Objective-C中是怎么工作的吗?,发现竟然做错了几道, 才知道自己想当然的理解是错误的,所以抽时间学习了下,并且通过一些测试代

mysql 里executeQuery在for循环里执行失效怎么解决?

问题描述 mysql 里executeQuery在for循环里执行失效怎么解决? 问题就是,之前是有时候可以上传图片,并被数据库记录,但会经常图片上传成功,数据库记录却没有. 在javabean的数据库里是这样创建conn 和 st 及rs的: public ft_con(){ if(conn==null){ try{ //Class.forName("com.microsoft.sqlserver.jdbc"); 基本不使用. //Class.forName("com.mi

php里怎么用foreach循环输出数据里的东西呢?

问题描述 php里怎么用foreach循环输出数据里的东西呢?

block循环引用解决

block循环引用解决 实验代码 @interface ViewController ()@property (nonatomic, strong) TestNetworkBlock *testNetwork;@end @implementation ViewController (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a

问一个C#里动态取得控件引用的函数

问题描述 一个界面里有N张图片,其id分别是pic1....picN还有一个输入框,供用户输入来取得某一张图片的引用,比如我输入pic2,然后按"确定"按钮,那个id为pic2的图片就会有动作(至于什么动作目前不谈)然后我现在的困难是如何得到那个引用呢?输入框得到的是String值,另外一个是Control对象,如何将它们对应起来?续:后来我在网上搜到一个叫Control.FindControl()的函数似乎可以实现我想要的效果,于是我在MSDN中找该函数的信息,它属于System.w

C#里枚举类型以及值引用和地址引用差别演示代码

在其它语言里,都已了解到.但还是写出来,印象深点. 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace ConsoleApplication2 8 { 9 class Program 10 { 11 enum MyDate 12 { 13 Sun = 0, 14 Mon

Unity Application Block 1.0系列(6):杜绝循环引用

在介绍 Constructor Injection.Property Injection和 Method Call Injection时,都有特别提到不要出现循环引用(Circular References),因为出现这种问题后很难去检测到.最好的解决方法是写代码时候尽量避免出现这种情况. 下面看看循环引用的几个场景,在使用依赖注入框架时应该尽量避免出现这样的情况: 1.通过Constructor Injection生成的对象在构造器的参数中互相引用 public class Class1{ p

c# 如何在Dictionary 里value保留数组的引用

问题描述 class1{ String[]str1; String[]str2;Dictionary<string,String[]>classHolder;方法1{classHolder=newDictionary<string,String[]>();classHolder.Add("1", str);classHolder.Add("2", str2);}方法2{ String[]str1=null; String[]str2=null