关于内存管理:iOS5中强弱存储的说明

Explanation of strong and weak storage in iOS5

我对ios5的开发和使用objective-c是个新手,我很难理解强存储和弱存储之间的区别。我已经阅读了文档和其他的SO问题,但它们听起来都和我一样,没有进一步的见解。

我阅读了文档:转换为ARC-IT引用了IOS4保留、分配和发布条款;这让我很困惑。然后,我研究了open u cs193p,它区分强弱:

Strong:"keep this in the heap until I don't point to it anymore"
Weak:"keep this as long as someone else points to it strongly"

两个定义是否相同=如果指针不再指向某个对象,则释放持有该对象的内存?我理解指针、堆、内存分配或释放的概念——但是强内存和弱内存有什么区别?


不同的是,一旦对象没有强指针,它就会被释放。即使弱指针指向它,一旦最后一个强指针消失,对象将被释放,所有剩余的弱指针将被清零。

也许有一个例子是正确的。

想象一下我们的目标是一只狗,而这只狗想逃跑(被释放)。

有力的指针就像狗身上的皮带。只要你把皮带系在狗身上,狗就不会跑掉。如果五个人把他们的皮带系在一只狗上(五个有力的指针指向一个物体),那么这只狗不会逃跑,直到五条皮带都被解开。

另一方面,弱指针就像小孩子指着狗说"看!狗!"只要狗还系着皮带,孩子们仍然能看到狗,他们还会指着它。不过,只要所有的皮带都断开,狗就会跑开,不管有多少小孩指着它。

一旦最后一个强指针(皮带)不再指向某个对象,该对象将被释放,所有弱指针都将归零。


Aren't the two definition identical.

绝对不是。你所指出的两个定义的关键区别在于"和别人一样长"。重要的是"其他人"。

考虑以下内容:

1
2
__strong id strongObject = <some_object>;
__weak id weakObject = strongObject;

现在我们有两个指针指向,一个强一个弱。如果我们把strongObject设为nil的话:

1
strongObject = nil;

然后,如果你通过你概述的规则,你会问你自己这些问题:

  • 斯特朗:"把这个放在堆里,直到我不再指向它。"

    strongObject不再指向。所以我们不需要保留它。

  • 弱者:"只要有人强烈地指向它,就保持这个"

    weakObject仍然指向。但由于没有其他人指向它,这条规则也意味着我们不需要保留它。

  • 结果是,被释放,如果运行时支持它(lion和ios 5向上),那么weakObject将自动设置为nil

    现在考虑一下,如果我们将weakObject设置为nil,会发生什么情况:

    1
    weakObject = nil;

    然后,如果你通过你概述的规则,你会问你自己这些问题:

  • 斯特朗:"把这个放在堆里,直到我不再指向它。"

    strongObject的确指向。所以我们需要保留它。

  • 弱者:"只要有人强烈地指向它,就保持这个"

    weakObject没有指向

  • 结果是,没有被释放,但weakObject将是nil指针。

    [请注意,假设不是由其他地方的另一个强引用/其他被"持有"的方式指向的]


    另一个例子:学生是Object,假设只要她/他完成了所有核心课程(strong pointers),就可以毕业(deallocate),不管她/他是否选修(weak pointers)。换句话说:强指针是该Object的唯一释放因素。


    强的

  • 在属性和指定值之间创建所有权。
  • 这是ARC中对象属性的默认值,因此它不会让您担心引用计数并自动释放引用。
  • 它是保留的替代品。我们只在需要用作保留时使用。
  • 弱的

  • 在属性和指定值之间创建非所有权。
  • 强用于父对象,弱用于子对象。当释放父对象时,子对象引用也设置为零。
  • 它有助于防止保留周期。
  • 当垃圾收集器收集时,它不保护引用的对象。
  • 弱者本质上是被赋予的,不存在的属性。

  • 我知道我参加这个聚会有点晚,但我认为重要的是要把这个问题搞混,指出"强内存和弱内存模型"的含义取决于你是在谈论软件还是硬件。

    对于硬件,弱或强表示是否支持顺序一致性。

    [SC means that]...the result of any execution is the same as if the operations of all
    the processors were executed in some sequential order, and the
    operations of each individual processor appear in this sequence in the
    order specified by its program. - Lamport, 1979

    那和记忆有关吗?这意味着不同处理器对变量的写入必须以相同的顺序被所有处理器看到。在具有强大型号的硬件中,这是有保证的。在弱模型的硬件上,它不是。

    现有的答案只能用软件内存模型来解释这个问题。硬件与编程无关。这个问题涉及到iOS,它通常运行在ARM7处理器上。ARM7有一个弱内存模型。对于习惯于使用强大模型的处理器的程序员来说,这是一个可怕的陷阱,因为x86和X64都有强大的模型。在强模型中,使用bool向另一个线程发出退出的信号可以很好地工作。ARM上的同一个代码根本不起作用,除非您将标志标记为易失性的,甚至它是不稳定的。

    虽然arm8+确实在明确支持获取/发布的情况下彻底改变了这一点,但传统软件不使用这种支持。传统的软件包括所有三个手机操作系统和它们上面运行的所有东西,以及编译器和库,直到它们被更新。

    对于这个话题的扩展检查,我指的是独一无二的药草萨特。


    不,它们不完全相同,但非常不同。只有在需要保留对象时才使用强。在任何其他情况下都使用weak,这样做的好处是,您可以知道对象ha是否已从堆中删除,因为没有人保留它。