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 ...
随机推荐
- python redis 发布订阅 实现 RPC同步
工作中用到的场景是,python主程序发布消息到Redis,然后停住等待Redis上订阅的Response.等待过程是阻塞的,相当于把异步通信封装成同步通信,类似于Java的RPC. RPC封装的代码 ...
- DBA_2PC_PENDING (转)
DBA_2PC_PENDINGOracle会自动处理分布事务,保证分布事务的一致性,所有站点全部提交或全部回滚.一般情况下,处理过程在很短的时间内完成,根本无法察觉到.但是,如果在commit或rol ...
- 1_python小程序之实现用户的注册登陆验证功能
python小程序之实现用户的注册登陆验证功能 程序扼要简述: 一.程序流程:1.程序开始2.判断本地文件/数据库是否已存在用户信息,存在则跳转到登陆,否则跳转到注册,注册成功后后跳转到登陆3.判断 ...
- 深入浅出 Java Concurrency (10): 锁机制 part 5 闭锁 (CountDownLatch)
此小节介绍几个与锁有关的有用工具. 闭锁(Latch) 闭锁(Latch):一种同步方法,可以延迟线程的进度直到线程到达某个终点状态.通俗的讲就是,一个闭锁相当于一扇大门,在大门打开之前所有线程都被阻 ...
- 使用ssh client与bash scripts轻松管理多台主机
当我们需要控制一个局域网中的很多台服务器时,一个简单的全局操作可能会被放大地异常繁琐,这时我们就会需要新的工具来快速完成这种工作. 我们将使用ssh客户端提供的一些工具来快速完成这一开发工作,我们的开 ...
- 「小程序JAVA实战」springboot的后台搭建(31)
转自:https://idig8.com/2018/08/29/xiaochengxujavashizhanspringbootdehoutaidajian31/ 根据下面的图,我们来建立下对应的sp ...
- C语言清空输入缓冲区的N种方法对比(转)
C语言中有几个基本输入函数: //获取字符系列 int fgetc(FILE *stream); int getc(FILE *stream); int getchar(void); //获取行系列 ...
- nginx实现多个域名共享80端口
server { listen 80; server_name server8085.duchong.cn; location / { proxy_pass http://127.0.0.1:8085 ...
- Keepalive VIP 故障
前端环境如下: Nginx + Keepalived ( MASTER ) --> node * | | Cisco ASA --> VIP 1.18 | | Nginx + Keepal ...
- 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 9_Neural Networks learning
神经网络的学习(Neural Networks: Learning) 9.1 代价函数 Cost Function 参考视频: 9 - 1 - Cost Function (7 min).mkv 假设 ...