了解使用其中访问self的块来保留计数。

时间:2015-01-02 13:44:00

标签: ios objective-c iphone objective-c-blocks weak-references

我对块的弱引用有基本的了解。我面临的问题是,

每当我在块中访问 self 时,self的保留计数会增加 2 ,就像我在默认块(例如UIViewAnimation)中访问self一样自我保留计数增加1。

只是想明白为什么它会增加2倍。 enter image description here

提前致谢!

2 个答案:

答案 0 :(得分:1)

根据用于生成Objective-C块代码的Clang源代码。

Objective-C blocks literal由EmitBlockLiteral函数生成。

llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {

LLVM document深刻解释了什么是块文字。无论如何,这个函数生成一个块描述符和指定块的复制辅助函数。复制助手功能用于捕获自动变量和self

buildBlockDescriptor -> buildCopyHelper -> GenerateCopyHelperFunction

GenerateCopyHelperFunction函数中,Clang为每个将被块捕获的Objective-C对象自动变量发出objc_storeStrong

for (const auto &CI : blockDecl->captures()) {
    ...
    EmitARCStoreStrongCall(...

因此,此行会计算self(1 - > 2)的保留计数。

之后,EmitBlockLiteral函数也会为每个将被块捕获的Objective-C对象自动变量发出objc_retain

// Next, captured variables.
for (const auto &CI : blockDecl->captures()) {
    ...
    EmitExprAsInit -> EmitScalarInit -> EmitARCRetain

因此,此行也会计算self的保留计数(2 - > 3)。

我不知道具体原因。但显然,有一些理由在通过块复制助手函数捕获对象之前保留Objective-C对象。

答案 1 :(得分:-1)

在块中使用self,通常会创建一个循环,这可能是它增加2的原因。要解决这个问题,你应该尝试使用弱自我。检查这个问题

capturing self strongly in this block is likely to lead to a retain cycle

使用类似的东西
    __unsafe_unretained typeof(self)weakSelf = self;