How do I avoid capturing self in blocks when implementing an API?
Short answerInstead of accessing
The If you are using ARC, the semantics of Long answerLet's say you had code like this:
The problem here is that self is retaining a reference to the block; meanwhile the block must retain a reference to self in order to fetch its delegate property and send the delegate a method. If everything else in your app releases its reference to this object, its retain count won't be zero (because the block is pointing to it) and the block isn't doing anything wrong (because the object is pointing to it) and so the pair of objects will leak into the heap, occupying memory but forever unreachable without a debugger. Tragic, really. That case could be easily fixed by doing this instead:
In this code, self is retaining the block, the block is retaining the delegate, and there are no cycles (visible from here; the delegate may retain our object but that's out of our hands right now). This code won't risk a leak in the same way, because the value of the delegate property is captured when the block is created, instead of looked up when it executes. A side effect is that, if you change the delegate after this block is created, the block will still send update messages to the old delegate. Whether that is likely to happen or not depends on your application. Even if you were cool with that behavior, you still can't use that trick in your case:
Here you are passing
This solution avoids the retain cycle and always calls the current delegate. If you can't change the block, you could deal with it. The reason a retain cycle is a warning, not an error, is that they don't necessarily spell doom for your application. If You could also look into using a similar trick above, declaring a reference weak or unretained and using that in the block. For example:
All three of the above will give you a reference without retaining the result, though they all behave a little bit differently: What's best will depend on what code you are able to change and what you cannot. But hopefully this has given you some ideas on how to proceed. |
|||||||||||||||||||||||||||||||||
|


|
There’s also the option to suppress the warning when you are positive that the cycle will get broken in the future:
That way you don’t have to monkey around with |
|||||||||||||||
|
|
I believe the solution without ARC also works with ARC, using the EDIT: Per the Transitioning to ARC Release Notes, an object declared with
|
|||||||||||||||||||||
|
|
For a common solution, I have these define in the precompile header. Avoids capturing and still enables compiler help by avoiding to use
Then in code you can do:
|
How do I avoid capturing self in blocks when implementing an API?的更多相关文章
- Some good iOS questions
这里,我列举了一些在Stackoverflow中一些比较好的关于iOS的问题.大部分我列举的问题都是关于Objective C.所有问题中,我比较喜欢“为什么”这一类型的问题. 问题 1. What’ ...
- [转]JavaScriptCore and iOS 7
原文:http://www.bignerdranch.com/blog/javascriptcore-and-ios-7/ As a rule, iOS programmers don't think ...
- [转]UIWebView的Javascript运行时对象
An alternative, that may get you rejected from the app store, is to use WebScriptObject. These APIs ...
- 【Orleans开胃菜系列2】连接Connect源码简易分析
[Orleans开胃菜系列2]连接Connect源码简易分析 /** * prism.js Github theme based on GitHub's theme. * @author Sam Cl ...
- C++ Core Guidelines
C++ Core Guidelines September 9, 2015 Editors: Bjarne Stroustrup Herb Sutter This document is a very ...
- x264源代码简单分析:滤波(Filter)部分
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- Async Performance: Understanding the Costs of Async and Await
Stephen Toub Download the Code Sample Asynchronous programming has long been the realm of only the m ...
- .NET Best Practices
Before starting with best practices tobe followed, it is good to have clear understanding of how mem ...
- Architecture of a Java Compiler
Architectural Overview A modern optimizing compiler can be logically divided into four parts: Th ...
随机推荐
- Codeforces-591C题解
一.题目链接 http://codeforces.com/problemset/problem/591/C 二.题意 给定一个只含数字0和1的数组,通过如下方式,变成不再变化的01组合,最少需要操作几 ...
- IDA Pro 权威指南学习笔记(十一) - 名称与命名
多数情况下,要修改一个名称,只需单击想要修改的名称(使其突出显示),并使用快捷键 N 打开更名对话框 右击需要修改的名称,并在出现的上下文菜单中选择 Rename 选项,也可以更改名称 参数和局部变量 ...
- [POJ] Bode Plot
Description Consider the AC circuit below. We will assume that the circuit is in steady-state. Thus, ...
- Spring中引质增强的安全
在引质增强中使用ThreadLocal变量,是因为控制状态使代理类变成了非线程安全的实例,为了解决单线程安全的问题,通过ThreadLocal让每个线程单独使用一个状态.
- springmvc 使用ajx上传文件 不设置form enctype
最近在做一个小项目 碰到这个问题 解决方案如下 1.js代码如下 获取当前form 转换为formdata ajax提交到后台 var form = $("#importForm" ...
- Install MongoDB Community Edition on Ubuntu
Install MongoDB > Install MongoDB Community Edition > Install MongoDB Community Edition on Lin ...
- [转] C#2010 在TreeView控件下显示路径下所有文件和文件夹
原文 张丹-小桥流水,C#2010 在TreeView控件下显示路径下所有文件和文件夹 C#2010学习过程中有所收获,便总结下来,希望能给和我一样在学习遇到困难的同学提供参考. 本文主要介绍两个自定 ...
- K2 Blackpearl中从数据库直接删除流程实例之K2Server表
转:http://www.cnblogs.com/dannyli/archive/2012/11/29/2794772.html /********************************** ...
- halcon 如何把一个region截取出来保存为图像
read_image(Image,'monkey') gen_circle(region,200,200,150) reduce_domain(Image,region,Mask) crop_doma ...
- PHP函数内访问全局变量
$dbcon='123'; 方法一.funtion fun1(){global $dbcon;$dbcon-> 就可以访问了.} 方法二$GLOBALS['$dbcon'];