我是iOS5开发新手并使用objective-c。我无法理解强和弱存储之间的区别。我已经阅读了文档和其他SO问题,但它们听起来与我完全相同,没有进一步的见解。
我读了the documentation: Transitioning To ARC - 它引用了iOS4的retain,assign和release术语;这让我很困惑。然后我查看Open U CS193p,它区分强弱:
强:“将它保留在堆中,直到我不再指向它”为止 弱:“只要别人强烈指出它就保持这个”
两个定义是否相同=如果指针不再指向一个对象,那么释放持有该对象的内存?我理解指针,堆,分配或释放内存的概念 - 但强弱之间有什么区别?
答案 0 :(得分:506)
不同之处在于,只要没有强指针,对象就会被释放。即使弱指针指向它,一旦最后一个强指针消失,对象将被释放,所有剩余的弱指针将被清零。
也许一个例子是有序的。
想象一下,我们的对象是一只狗,狗想要逃跑(被解除分配)。
强壮的指针就像是狗的皮带。只要你的皮带附着在狗身上,狗就不会逃跑。如果有五个人将他们的皮带连接到一只狗上(五个指向一个物体的强力指针),那么只要五条皮带脱落,狗就不会逃跑。
另一方面,弱点就像小孩子指着那只狗说“看!一只狗!”只要狗仍然在皮带上,小孩子仍然可以看到狗,他们仍然会指向它。然而,一旦所有的皮带脱落,无论有多少小孩指向它,狗都会逃跑。一旦最后一个强指针(皮带)不再指向一个对象,该对象将被释放,并且所有弱指针都将被清零。
答案 1 :(得分:34)
这两个定义不一样吗。
绝对不是。您指出的两个定义的主要区别在于“只要其他人”。这是“别人”,这很重要。
请考虑以下事项:
__strong id strongObject = <some_object>;
__weak id weakObject = strongObject;
现在我们有两个指向<some_object>
的指针,一个是强,一个是弱。如果我们将strongObject
设置为nil
,请执行以下操作:
strongObject = nil;
然后,如果你遵守你概述的规则,那么你会问自己这些问题:
强:“将它保留在堆中,直到我不再指向它”
strongObject
不再指向<some_object>
。所以我们不需要保留它。
弱:“只要别人强烈指出它就保持这个”
weakObject
仍然指向<some_object>
。但由于没有人 else 指向它,这条规则也意味着我们不需要保留它。
结果是<some_object>
被取消分配,如果您的运行时支持它(Lion和iOS 5以上),则weakObject
将自动设置为nil
。
现在考虑如果我们将weakObject
设置为nil
会发生什么情况:
weakObject = nil;
然后,如果你遵守你概述的规则,那么你会问自己这些问题:
强:“将它保留在堆中,直到我不再指向它”
strongObject
确实指向<some_object>
。所以我们确实需要保留它。
弱:“只要别人强烈指出它就保持这个”
weakObject
未指向<some_object>
。
结果是<some_object>
不已取消分配,但weakObject
将是nil
指针。
[请注意,假设<some_object>
的所有内容都未被其他地方的其他强引用指向/某些其他方式被“持有”]
答案 2 :(得分:2)
强
弱
答案 3 :(得分:2)
另一个例子:
学生是Object
,假设她/他可以毕业(deallocate
),只要她/他完成所有核心课程(strong pointers
),无论她/他是否选择-courses(weak pointers
)。换句话说:强指针是释放Object
的唯一因素。
答案 4 :(得分:1)
不,它们不完全相同但非常不同。仅在需要保留对象时才使用strong。你在任何其他情况下使用弱,你可以知道是否已经从堆中删除了对象,因为没有人保留它。
答案 5 :(得分:1)
我知道我在这个派对上已经很晚了,但我认为通过指出“强弱记忆模型”的含义来混淆这个问题很重要。取决于你是在谈论软件还是硬件。
对于硬件,弱或强表示是否支持顺序一致性。
[SC表示] ......执行的结果与所有操作的结果相同 处理器按顺序执行,并且 每个处理器的操作按此顺序出现在 其程序指定的订单。 - Lamport, 1979
WTF是否与记忆有关?这意味着所有处理器必须以相同的顺序看到不同处理器对变量的写入。在具有强大型号的硬件中,这是有保证的。在具有弱模型的硬件上,它不是。
现有答案仅在软件内存模型方面解释问题。硬件与编程无关。这个问题提到了iOS,它通常在Arm7处理器上运行。 Arm7具有弱内存模型。对于习惯于具有强大模型的处理器的程序员 - 我们所有人都是因为x86和x64具有强大的模型 - 这是一个可怕的陷阱。使用bool来指示另一个线程退出在强模型中正常工作。除非你将旗帜标记为易失性,否则Arm上的相同代码根本不起作用,即使这样它也不稳定。
虽然Arm8 +确实在明确支持获取/发布的情况下完全改变了这一点,但遗留软件并没有使用这种支持。传统软件包括所有三个手机操作系统及其上运行的所有内容,以及编译器和库,直到更新为止。
对于此主题的扩展检查,我建议您使用无法模仿的Herb Sutter。