在这种情况下,ARC 是否会保留 self?

4
我可以帮您进行翻译。以下是一种可能的版本:

我在一个方法中写了如下代码:

UIImageView* imageBlk = self.image;
self.finishBlock = ^{
    imageBlk.hidden = YES;
}

在ARC中,由于image是self的一个属性,所以self会被block保留吗?谁拥有imageBlk?是Self吗?


请查看 http://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html 中的块章节,也许这篇博客文章可以澄清你的问题。 - CarlJ
3个回答

2

代码块会保留self吗?不会。 imageBlk变量不是实例变量,因此代码块没有必要保留self。在您发布的代码中不必担心引用循环。

imageBlk由谁拥有?imageBlk是一个堆栈变量。代码块将保留该变量。ARC负责保留它,并在适当时释放它。

self由谁拥有?我们无法从这段代码中回答。谁分配了对象,谁就拥有它。谁保留它也拥有它。


有道理,但引出了另一个问题,我会在另一个线程中提问。如果imageblk是实例变量,为什么块要保留self(它是否对私有ivar和属性都这样做?)保留对象本身应该足以确保其存在,那么为什么还要保留self? - Meda
请参阅“在捕获self时避免强引用循环”:https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html - rmaddy

0
不,因为imageBlkself.image不同!imageBlk是一个本地变量,没有任何人拥有它。块内的imageBlkimageBlk的只读副本,而不是同一变量。如果你想让它成为同一变量,你必须使用__block声明。

如果imaBlk没有被任何人拥有,谁负责在作用域结束时释放它?我认为默认情况下,变量会被保留,而不是在块内复制。指针是一个副本,就像在任何其他C函数中一样,但它指向的对象应该是实际的对象。如果你是正确的,只有实现了NSCopying的实例才能被传递到块内。所以问题仍然存在。 - Meda
@Meda 如果你正在使用ARC,它会在作用域结束时负责调用release,否则你会负责,但不是self。如果没有__block说明符声明的块外变量,在块内是只读的。你不能在块内给imageBlk赋新值。一个对象不同于一个变量。内部和外部的对象是相同的,但变量不是。 - Jonathan Cichon

0

代码没问题。 在块外声明的变量是只读的,你不能改变它的值。
但是...你并没有改变这个值!你只是在这个值上“调用了一个方法”,即[imgBlock setHideen:YES];
完全合法。一切都将无缝地运行。块会保留imgView直到不再需要。


你说的没错,但你没有回答问题 - self 会被 block 保留吗? - rmaddy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接