Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 理解保留计数和块访问自身内部。_Ios_Objective C_Iphone_Objective C Blocks_Weak References - Fatal编程技术网

Ios 理解保留计数和块访问自身内部。

Ios 理解保留计数和块访问自身内部。,ios,objective-c,iphone,objective-c-blocks,weak-references,Ios,Objective C,Iphone,Objective C Blocks,Weak References,我对块的弱引用有一个基本的理解。我面临的问题是, 每当我在块内访问selfself时,self的保留计数将增加2,其中当我在默认块内访问self时(例如UIViewAnimation),self的保留计数将增加1 只是想了解为什么它会增加2。 提前谢谢 在块内使用self通常会创建一个循环,这可能是它增加2的原因。要解决这个问题,你应该尝试使用弱自我。看看这个问题 使用类似这样的工具 __不安全(自我)未恢复的弱点类型self=自我; 根据Clang源代码生成Objective-C块代码

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

每当我在块内访问selfself时,self的保留计数将增加2,其中当我在默认块内访问self时(例如UIViewAnimation),self的保留计数将增加1

只是想了解为什么它会增加2。


提前谢谢

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

使用类似这样的工具

__不安全(自我)未恢复的弱点类型self=自我;

根据Clang源代码生成Objective-C块代码

Objective-C blocks文本由
EmitBlockLiteral
函数生成

llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
深入解释什么是块文字。无论如何,此函数生成指定块的块描述符和复制辅助函数。复制帮助器功能用于捕获自动变量和
self

buildBlockDescriptor -> buildCopyHelper -> GenerateCopyHelperFunction
generateCyHelperFunction
函数中,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对象是有原因的。

块将希望保留“捕获的”IVAR(如self),以确保引用仍然有效。。。即
self
在执行之前不会解除分配。你会在这里找到这方面的好信息(MRC和ARC的处理方式不同。为了更好地理解弱读@YvesLeBorg,感谢分享链接。我只是检查了该特定情况下块的行为,结果是2。ARC运行时,查看保留计数绝对没有意义。它只会让你感到困惑。很少有结论是您可以从任何保留计数中得出什么,当涉及ARC时,根本没有有效的结论。在块内使用
self
不会创建一个循环。它会创建一个从块到
self
的引用。它只会创建一个循环,如果您创建了一个循环——如果您保留了从
self
到块的引用。这不是hap在这里开门。
llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {