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 ...
随机推荐
- Mac Terminal终端光标的快捷键操作
2016年08月18日 18:26:06 阅读数:4217 Mac Terminal终端和linux上终端光标的快捷键操作是一样的,都是来自Emacs这个神级的编辑器,由于我以前vim用的多,没怎么用 ...
- Spring源码加载过程图解(一)
最近看了一下Spring源码加载的简装版本,为了更好的理解,所以在绘图的基础上,进行了一些总结.(图画是为了理解和便于记忆Spring架构) Spring的核心是IOC(控制反转)和AOP(面向切面编 ...
- PHP redis client封装
config1.inc.php if (!isset($_REQUEST['pageName']) || $_REQUEST['pageName'] != 'txl-app-test') { $CON ...
- 魔术方法以及__call的调用
一.什么是魔术方法? 魔术方法是php中对一类方法的统称,这些方法可以在任何类中被实现.他们通常可以完成一些特殊的无法纯粹依靠自己编程实现的功能.他们通常以双下划线"__"作为名称 ...
- Flask之模板web表单
3.3 Web表单: web表单是web应用程序的基本功能. 它是HTML页面中负责数据采集的部件.表单有三个部分组成:表单标签.表单域.表单按钮.表单允许用户输入数据,负责HTML页面数据采集,通过 ...
- 4、数据类型二:Lists
1.关于list的组织形式 列表数据类型(Lists)可以存储一个有序的字符串列表,常用的操作时向列表两段添加元素,或者获取列表的某一个片段.列表类型的底层实现是一个双向链表(double linke ...
- Rhythmk 一步一步学 JAVA (13) Spring-2 之Ben懒加载以及生命周期,单例
1.定义Demo类: package com.rhythmk.spring; public class User { public void Init () { System.out.println( ...
- create-react-app react脚手架
create-react-app react脚手架 官方脚手架 1.安装 npm install -g create-react-app 2.创建项目 create-react-app react-c ...
- Django创建一个简单的blog
1. 使用django-admin.py 创建mysite项目 sunny@sunny-ThinkPad-T450:~/PycharmProjects$ django-admin.py startpr ...
- Linux实战教学笔记42:squid代理与缓存实践(一)
第1章 Squid介绍 1.1 缓存服务器介绍 缓存服务器(英文意思cache server),即用来存储(介质为内存及硬盘)用户访问的网页,图片,文件等等信息的专用服务器.这种服务器不仅可以使用户可 ...