【问题标题】:How to release object when using block callback使用块回调时如何释放对象
【发布时间】:2011-09-01 00:24:18
【问题描述】:

这可能是关于内存管理的新手问题。

在目标 c 中使用块作为回调时如何释放对象?

(更新代码)

@implementation ObjectWithCallback
- (void)dealloc {
    [_completionHandler release];
    [super dealloc];
}
- (void)doTaskWithCompletionHandler:(void(^)(void))handler {
    _completionHandler = [handler copy];
    // Start tasks...
}
- (void)tasksDone {
    // Do callback block
    _completionHandler();
    // Delete reference to block
    [_completionHandler release];
    _completionHandler = nil;
}

// Use of the ObjectWithCallback
ObjectWithCallback *request = [[ObjectWithCallback alloc] init];
[request doTaskWithCompletionHandler:^(void){
    // Callback called and task is ready.
}];

【问题讨论】:

  • 你要释放什么对象,为什么不能在块内释放?
  • 是什么让你觉得你无法释放块中的对象?
  • 他要释放request。

标签: iphone objective-c memory-leaks callback objective-c-blocks


【解决方案1】:

快速但不完整的答案:[request autorelease]

这样做的问题是,块隐式地保留了块主体内引用的任何对象。所以块保留request,request 保留块,导致保留循环,没有人被释放。

为了解决这个问题,您将 request 变量声明为 __block,这会阻止块保留捕获的对象:

__block ObjectWithCallback *request = [[ObjectWithCallback alloc] init];

推荐阅读:

【讨论】:

  • __block 不应在这种情况下使用。对象的生命周期显然与块相关联,而块的保留确保了这一点。
  • @bbum 我想我明白你的意思,但是如果块引用request,这是否仍会导致保留周期?我想一种解决方法是让ObjectWithCallback 在调用它之后释放回调块。
  • 啊——是的——与 OP 的问题正交的不同问题。德普。
  • 感谢您的回答,我将深入研究您的阅读技巧。似乎它可能是一个保留周期。我以为我从对象中释放了对块的引用,但它似乎不起作用(代码已更新)
  • 查看更新后的代码,因为您是在调用块后释放块,所以您应该能够简单地在块内执行[request release] 并让一切正常工作。如果你这样做会发生什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 2014-03-15
  • 2012-05-04
  • 2011-05-13
  • 1970-01-01
  • 1970-01-01
  • 2016-08-18
相关资源
最近更新 更多