iOS5中强弱存储的说明


114

我是iOS5开发的新手,正在使用Objective-C。我很难理解存储和存储之间的区别。我已经阅读了文档和其他SO问题,但是它们听起来与我完全相同,没有进一步的了解。

我阅读了以下文档:过渡到ARC-引用了iOS4的保留,分配和发布条款;这让我感到困惑。然后,我看一下Open U CS193p,它区分强项和弱项:

:“将其保留在堆中,直到我不再指向它为止”
:“只要其他人强烈将其保留,则保留此”

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


即使使用ARC,内存管理模型仍然有用。您仍然必须了解引用计数,而不必手动进行。因此,您的最后一段是不合理的要求。
jrturton

Answers:


509

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

也许有个例子。

想象我们的对象是一只狗,那只狗想逃跑(被释放)。

强壮的指针就像拴在狗身上的皮带。只要您将皮带拴在狗上,狗就不会跑开。如果有五个人将皮带拴在一只狗上(五个强力指针指向一个物体),则只有将所有五个皮带分开后,狗才会逃跑。

另一方面,弱指针就像小孩指着狗说:“看!狗!” 只要这只狗仍系在皮带上,小孩子仍然可以看到它,他们仍会指向它。但是,一旦所有的皮带都松了,无论有多少小孩指向它,狗都会跑开。

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


2
它是基于几年前苹果公司的Malcom Crawford的类比。不知道他从哪里得到的。
BJ Homer '02

我记得在一本书中读过类似的文章(电弧前),认为那是Hillegass,但他本可以从其他地方得到的……虽然那是个好东西!
jrturton

14
+1个出色的例子。这是Hillegass关于如何保持/释放皮带的例子的衍生,但我喜欢这种适应强/弱的方法。
戴夫·德隆

2
@DaveDeLong:嗯,在ARC 10.6上它们是非法的。您根本无法使用它们。所以这有点不重要。
BJ荷马

5
另一个好的气球是氦气球:只要握住至少一根绳子,它就不会漂浮。皮带/气球的类比也很容易使人们忘记“所有权”是由保留/释放来管理的。
史蒂夫·韦勒

34

这两个定义不完全相同。

绝对不。您指出的两个定义的主要区别是“只要有人”。重要的是“其他人”。

考虑以下:

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

现在我们有两个指向的指针<some_object>,一个是强项,另一个是弱项。如果我们设置strongObjectnil像现在这样:

strongObject = nil;

然后,如果您遵循列出的规则,则会问自己以下问题:

  1. 强:“将其保留在堆中,直到我不再指向它为止”

    strongObject不再指向<some_object>。因此,我们不需要保留它。

  2. 弱:“只要有人坚决指出,就保持下去”

    weakObject仍然指向<some_object>。但是由于没有指出它,因此该规则也意味着我们不需要保留它。

结果是<some_object>已解除分配,并且如果您的运行时支持它(Lion和iOS 5及更高版本),weakObject则将自动设置为nil

现在考虑如果我们设置发生了什么weakObjectnil,像这样:

weakObject = nil;

然后,如果您遵循列出的规则,则会问自己以下问题:

  1. 强:“将其保留在堆中,直到我不再指向它为止”

    strongObject确实指向<some_object>。所以我们确实需要保留它。

  2. 弱:“只要有人坚决指出,就保持下去”

    weakObject没有指向<some_object>

其结果是,<some_object>释放,但weakObject将是nil指针。

[请注意,所有假定的内容<some_object>都没有被其他地方的强引用/其他“持有”方式指出。


1
因此,强和弱之间的主要区别在于,指向强对象的释放将自动取消所有相关的弱指针。对于指向某物的弱指针,总会存在一个强指针。如果是这样,必须强烈指出主要的应用对象?
KMC 2012年

要使弱指针指向有效对象,则必须有强指针。再加上iOS 5和Lion支持自动补齐弱引用,您会得到您所要说的事实。iOS 4的的运行并不会支持,虽然。“主应用程序对象”我假设您是指UIApplication对象?这将由UIKit- 的内部工作原理强烈引用-但您不必为此担心。
mattjgalloway 2012年

我认为您可以使用“ strongObjectPointer”之类的词代替“ strongObject”。因此,编程新手将具有更好的意义。@BJ Homer发表的精彩文章,Matt.Mat.Interesting :)
Vijay-Apple-Dev.blogspot.com 2013年

2

强大

  1. 在属性和分配的值之间创建所有权。
  2. 这是ARC中对象属性的默认设置,因此您不必担心引用计数并自动释放引用。
  3. 它是保留的替代。我们仅在需要用作保留时使用。

  1. 在属性和分配的值之间创建非所有权。
  2. 当释放父对象时,在父对象上使用Strong,在子对象上使用weak,然后将子对象引用也设置为nil
  3. 它有助于防止保留周期。
  4. 当通过垃圾收集器进行收集时,它不保护引用的对象。
  5. 弱是本质上分配的,不保留的属性。

这里值得一提的是保留周期通常是什么。我们有两个对象:对象A和B.对象对象A具有很强的参考对象B和对象B具有很强的参考对象A.闲来无事具有很强的参考对象A或B.
博罗

2

另一个例子:学生是一个Object,假设deallocate她/他完成所有核心课程(strong pointers)即可毕业(),无论她/他是否修读可选课程(weak pointers)。换句话说:强指针是该对象释放的唯一因素Object


1

不,它们不是相同的,但有很大的不同。仅在需要保留对象时才使用Strong。在任何其他情况下,您都可以使用弱函数,这有一个缺点,即可以知道是否已从堆中删除了对象,因为没有人保留它。


1

我知道我参加这个聚会已经很晚了,但是我想指出这个问题很重要,因为指出“强而弱的内存模型”的含义取决于您在谈论软件还是硬件。

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

[SC表示] ...任何执行的结果都与按顺序执行所有处理器的操作相同,并且每个单独处理器的操作均按其程序指定的顺序按此顺序显示。- 兰帕特,1979年

WTF与内存有关吗?这意味着所有处理器必须以相同的顺序查看不同处理器对变量的写入。在具有强大模型的硬件中,这是可以保证的。在具有弱模型的硬件上,事实并非如此。

现有答案仅根据软件内存模型来解释问题。硬件与编程无关。这个问题提到了iOS,通常在Arm7处理器上运行。Arm7的内存模型较弱。对于习惯于具有强大模型的处理器的程序员-这就是我们所有人,因为x86和x64具有强大的模型-这是一个可怕的陷阱。在可靠的模型中,使用布尔值指示另一个线程退出很有效。除非您将标志标记为volatile,否则Arm上的相同代码根本无法工作,即使那样它也是不稳定的。

虽然Arm8 +确实通过对获取/发布的显式支持彻底改变了这一点,但旧版软件不使用此支持。旧版软件包括所有三个电话操作系统以及在其上运行的所有内容,以及在更新之前的编译器和库。

如果需要对该主题进行更深入的研究,请转至无与伦比的Herb Sutter

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.