了解目标C的弱项和强项

积木很棒。 为了避免保持周期,您经常会看到“弱者自我” —“强者自我”舞蹈

  __weak __typeof __(self)weakSelf =自我; 
self.block = ^ {
__typeof __(self)strongSelf = weakSelf;
[strongSelf doSomething];
[strongSelf doSomethingElse];
};

复制时块是对象

块在堆栈上创建,并且在其堆栈帧返回时将消失。 在堆栈上时,块对其所访问的任何内容的存储或生存期均无影响。

如果在堆栈帧返回后需要存在块,则可以将它们复制到堆中,并且此操作是显式操作。 这样,一个块将作为可可中的所有对象获得引用计数。 复制它们时,它们会随身携带其捕获的范围,并保留它们引用的所有对象

块可以从封闭范围捕获值

除了包含可执行代码之外,块还具有从其封闭范围捕获状态的能力。 请注意,代码块会捕获变量及其修饰符(即弱限定符),

=>这说明了为什么需要将self声明为 __weak

当执行块时,对于第一种方法(doSomething),weakSelf可能为非零;而对于第二种方法(doSomethingElse),不可以使weakSelf不为nil。

您可能会认为,起初,这是在块内使用self来避免保留周期警告的技巧。 不是这种情况。 在块执行时创建对self的强引用,而在块声明时评估在块中使用self,从而保留对象。

但是,为了获得最佳实践,应该使用弱对象为对象创建强引用。 这也不会创建一个保留周期,因为该块内的强指针仅在该块完成之前才存在(唯一的作用域是该块本身)。

=>这说明了为什么您需要声明另一个 __strong 自我

许多人指出,“块是在堆栈上创建的,当它们的堆栈帧返回时,它们就会消失。 在堆栈上时,块不会影响它所访问的任何内容的存储或生存期。”
即使块(在堆栈上声明)增加了对其访问的所有对象的引用计数,这也将是无用的,因为当函数返回时,该块将被丢弃

复制块时(您会看到人们通常为块声明属性(副本)),这将增加对其访问的所有对象的引用计数。

为什么? 因为块是要在以后的时间执行的,所以它需要保持对它访问的所有对象的强引用。 块可以执行很多次,所以运行后它不会释放自己。

当您取消该块时,它将被取消分配,因此将减少对其访问的所有对象的引用计数。

AFNetworking在调用该块后将其清除为零,因此您不必在块内使用weakself

因此,在某些情况下,您不必在块内使用weakself

  • 确保没有复制该块,只需声明并运行它
  • 确保该块在调用后为零

这是更多链接,可帮助您进一步探索

  • 我终于想出了弱自我和强自我
  • 使用块
  • Objective-C阻止警告
  • 引擎盖下的Objective-C块
  • 块内的外观:第1集
  • 块内外观:第2集
  • 深入了解区块:第3集
  • 从C声明符到Objective-C块语法
  • Objective-C块的语法
  • 指嵌套块内的弱自我
  • 捕捉我(自己)

原始故事https://github.com/onmyway133/blog/issues/164