iOS5强大和弱存储的解释
我是iOS5开发新手,使用Objective-C。 我很难理解储存强弱的区别。 我已经阅读了文档和其他SO问题,但是对于我来说,这些问题都没有进一步的了解。
我阅读文档:过渡到ARC – 它引用了iOS4的保留,分配和释放条款; 这使我困惑。 然后我看看Open U CS193p,它强调和弱点:
强 :“把它放在堆里,直到我不再指向它”
弱 :“只要别人强烈地指出这一点,就坚持下去”
这两个定义是不是相同的=如果指针不再指向一个对象,那么释放存储对象的内存? 我理解指针,堆,分配或释放内存的概念 – 但强弱之间有什么区别?
不同之处在于,只要没有强指针,对象就会被释放。 即使弱指针指向它,一旦最后一个强指针消失,对象将被释放,所有剩余的弱指针将被清零。
也许一个例子是为了。
想象一下,我们的目标是一只狗,而狗想逃跑(被释放)。
强壮的指针就像狗狗上的皮带。 只要你有狗的皮带,狗不会逃跑。 如果五个人把他们的皮带绑在一只狗身上(五个指向一个物体的强指针),那么在所有五个皮带脱离之前,狗不会跑掉。
另一方面,弱指针就像小孩子指着狗说:“看!一条狗!” 只要狗仍然在拴住,小孩们仍然可以看到狗,他们仍然指向它。 然而,只要所有的皮带都分离了,不pipe有多less小孩指着它,狗都会跑掉。
只要最后一个强指针(皮带)不再指向一个对象,该对象将被释放,所有弱指针将被清零。
这两个定义不一样吗?
绝对不。 你指出的两个定义的关键区别在于“只要别人”。 这是重要的“别人”。
考虑以下:
__strong id strongObject = <some_object>; __weak id weakObject = strongObject;
现在我们有两个指向<some_object>
指针,强一弱。 如果我们将strongObject
设置nil
如下所示:
strongObject = nil;
那么,如果你通过你勾画的规则,那么你会问自己这些问题:
-
强:“把它放在堆里,直到我不再指向它”
strongObject
不再指向<some_object>
。 所以我们不需要保留它。 -
弱:“只要别人强烈地指出这一点,就坚持下去”
weakObject
仍然指向<some_object>
。 但是由于没有人指出,这个规则也意味着我们不需要保留它。
结果是<some_object>
被释放,如果您的运行时支持它(Lion和iOS 5向上),那么weakObject
将被自动设置为nil
。
现在考虑如果我们将weakObject
设置weakObject
,会发生什么情况:
weakObject = nil;
那么,如果你通过你勾画的规则,那么你会问自己这些问题:
-
强:“把它放在堆里,直到我不再指向它”
strongObject
确实指向<some_object>
。 所以我们需要保留它。 -
弱:“只要别人强烈地指出这一点,就坚持下去”
weakObject
不指向<some_object>
。
结果是<some_object>
没有被释放,但weakObject
将是nil
指针。
[请注意,所有假设<some_object>
不是由另一个强引用指向其他地方/某些其他方式被“举行”]
强大
- 创build属性和分配值之间的所有权。
- 这是ARC中的对象属性的默认值,因此它不会让您担心引用计数并自动释放引用。
- 这是保留的替代。 我们使用当且仅当我们需要使用保留。
弱
- 在财产和分配的价值之间创build非所有权。
- 当父对象被释放时,强对象用于父对象,对子对象使用弱对象,子对象引用也被设置为零
- 这有助于防止保留周期。
- 垃圾收集器收集时,它不保护引用的对象。
- 实质上分配不足,没有财产。
不,它们并不完全相同,但却非常不同。 只有在需要保留对象的情况下才能使用强壮。 在任何其他情况下,你都可以使用弱点,你可以知道对象是否被从堆中移除,因为没有人保留它。
另一个例子:学生是一个Object
,不pipe他/她选修课程( weak pointers
),只要他/她完成了所有核心课程( strong pointers
),就可以gradle(去deallocate
)。 换句话说,强指针是该Object
的重新分配的唯一因素。
我知道我对这个晚会比较迟,但是我认为通过指出“强而弱的记忆模型”的含义取决于你是在谈论软件还是硬件,这是很重要的。
对于硬件,弱或强指示是否支持顺序一致性。
[SC表示] …执行的结果与所有处理器的操作以某种顺序执行的相同,并且每个单独的处理器的操作以其程序指定的顺序出现在该序列中。 – Lamport,1979
WTF是否与记忆有关? 这意味着不同处理器对variables的写入必须由所有处理器以相同的顺序来看待。 硬件与强大的模式,这是保证。 在弱模型的硬件上,事实并非如此。
现有的答案只是从软件内存模型的angular度来解释这个问题。 硬件与编程无关。 这个问题提到iOS,通常运行在Arm7处理器上。 Arm7有一个弱记忆模型。 对于习惯了处理器的程序员来说,强大的模型 – 这是我们所有人的,因为x86和x64有一个强大的模型 – 这是一个可怕的陷阱。 用一个bool来指示另一个线程退出在一个强大的模型中工作正常。 Arm上的相同代码根本不起作用,除非将标志标记为volatile,即使如此也是不稳定的。
虽然Arm8 +确实改变了这一点,但明确支持获取/发布,遗留软件不使用这种支持。 传统软件包括所有三个电话操作系统及其上运行的所有内容,以及编译器和库,直到它们被更新。
对于这个主题的扩展审查,我把你推荐给独特的草药萨特 。