使用 ARC 手动保留
Posted
技术标签:
【中文标题】使用 ARC 手动保留【英文标题】:Manual retain with ARC 【发布时间】:2011-12-09 04:59:40 【问题描述】:在 ARC 之前,我有以下代码在异步操作进行时保留委托:
- (void)startAsyncWork
[_delegate retain];
// calls executeAsyncWork asynchronously
- (void)executeAsyncWork
// when finished, calls stopAsyncWork
- (void)stopAsyncWork
[_delegate release];
ARC 与此模式的等价物是什么?
【问题讨论】:
【参考方案1】:我偶尔需要手动保留和释放东西(有时只是为了调试)并想出了以下宏:
#define AntiARCRetain(...) void *retainedThing = (__bridge_retained void *)__VA_ARGS__; retainedThing = retainedThing
#define AntiARCRelease(...) void *retainedThing = (__bridge void *) __VA_ARGS__; id unretainedThing = (__bridge_transfer id)retainedThing; unretainedThing = nil
这是通过使用 __bridge_retained 和 __bridge_transfer 将事物转换为 (void *) 来实现的,这会导致事物被保留,或者在不调用 retain 的情况下创建强引用。
玩得开心,但要小心!
【讨论】:
第一个宏这部分是什么原因:retainedThing = retainedThing
?
这是我防止编译器生成有关未使用变量的警告的方法。
谢谢,还是有用的!
这让我喜极而泣。在对 NSInvocations 进行了一些调整和摆弄之后,很明显我的返回值没有被保留足够长的时间来返回给调用者,所以我的一堆 hack 又获得了两个 hack。非常感谢。
这正是我想要的解决方案,但它对我不起作用。我收到“预期表达式”和“使用未声明的标识符“retainedThing”编译器错误。【参考方案2】:
为什么不在异步任务期间将您的委托对象分配给一个强 ivar?
或者在executeAsyncWork
中有一个局部变量
- (void)executeAsyncWork
id localCopy = _delegate;
if (localCopy != nil) // since this method is async, the delegate might have gone
// do work on local copy
【讨论】:
谢谢。这也是我的第一个想法。我希望会有另一个巧妙的技巧;-)。 @hypercrypt:GCD 不是让变量挂起的解决方案,但它是实际执行异步工作的一种特别好的方法。 @hypercrypt:我知道 GCD,但这不是这里的解决方案 ;-)。我正在使用 NSURLConnectionDelegate。【参考方案3】:类似这样的:
- (void)startAsyncWork
id<YourProtocol> delegate = _delegate;
dispatch_async(/* some queue */, ^
// do work
[delegate doSomething];
该块将根据需要保留委托...
【讨论】:
以上是关于使用 ARC 手动保留的主要内容,如果未能解决你的问题,请参考以下文章