【问题标题】:Objective-C - Blocks and memory management?Objective-C - 块和内存管理?
【发布时间】:2012-08-31 15:52:25
【问题描述】:
__weak MyClass *selfReference = self;

dispatch_async(dispatch_get_main_queue(), ^{
        [selfReference performSomeAction];
    });
  • 何时需要将弱引用传递给块?
  • 此规则是否适用于 dispatch_async 以及自定义块?
  • 块是复制其中使用的 iVar 还是保留它们?
  • 谁拥有在块内初始化的变量?谁应该释放它们?

【问题讨论】:

  • 这些问题在苹果的文档中都有解答。
  • @JonathanGrynspan 你可以给一个文档的指针吗?
  • @JonathanGrynspan developer.apple.com/library/ios/#documentation/cocoa/Conceptual/… 这是文档的链接,但它没有回答我的问题
  • @aryaxt:继续阅读。这一切都在那里。 :)
  • @Jonathan Grynspan 请注意,所引用的文档没有提及 ARC,但关于块 WRT ARC 的一些内容(例如 __block 现在创建了一个强引用)已经改变。

标签: objective-c memory-management objective-c-blocks


【解决方案1】:

1, 2) 块在其中保留对象指针(任何块,dispatch_async 块都没有什么特别的)。这通常不是问题,但可能导致保留周期,因为块可以与所有者对象相关联,并且该所有者对象(通常self)可能会被块保留。在这种情况下,您应该使用弱变量,然后将其重新分配给强捕获:

__weak MyClass *weakSelf = self;
self.block = ^{
    MyClass *strongSelf = weakSelf;
    ...
    [strongSelf ...];
    [strongSelf.property ...];
    [strongSelf->iVar ...];
 }

注意:如果您直接访问 iVar,编译器会将其转换为 self->iVar 并因此保留 self!

3) 块只保留指针,不复制它们。

4) 在块内创建的变量属于该块,当该块超出范围时将被释放。

【讨论】:

  • Fabian,您能否评论一下为什么需要重新分配给强指针?
  • 如果您不创建强属性 1) 编译器禁止使用 -> 运算符并且您无法访问 iVars 并且 2) 弱变量可能会在块执行时被释放.为了确保在块执行时变量不会被释放,你必须在使用它之前将它分配给一个强变量。
  • 这个问题是针对 dispatch_async 的,但答案中没有解决。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-12
相关资源
最近更新 更多