ChatGPT解决这个技术问题 Extra ChatGPT

iOS5中强弱存储的解释

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

我阅读了 the documentation: Transitioning To ARC - 它引用了 iOS4 的保留、分配和释放条款;这让我很困惑。然后我研究了 Open U CS193p,它区分了强弱:

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

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

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

B
BJ Homer

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

也许一个例子是为了。

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

强指针就像狗的皮带。只要你把皮带拴在狗身上,狗就不会逃跑。如果五个人将他们的皮带拴在一只狗身上(五个强指针指向一个物体),那么在所有五根皮带都脱离之前,狗不会逃跑。

另一方面,弱指针就像小孩子指着狗说“看!一条狗!”只要狗还在皮带上,小孩子仍然可以看到狗,他们仍然会指向它。然而,一旦所有的皮带都松开了,不管有多少小孩指着它,狗都会跑掉。

一旦最后一个强指针(leash)不再指向一个对象,这个对象就会被释放,所有的弱指针都会被清零。


它基于几年前苹果公司 Malcom Crawford 的一个类比。不知道他从哪里弄来的。
我记得在一本书中读过类似的东西(弧前),以为是希勒加斯,但后来他本可以从其他地方得到它……不过,这是一本好书!
+1 很好的例子。它是 Hillegas 关于如何保留/释放皮带的示例的衍生产品,但我喜欢这种针对强/弱的改编。
@DaveDeLong:好吧,他们在 10.6 上使用 ARC 是非法的。你根本不能使用它们。所以这有点无关紧要。
另一个不错的是氦气球:只要至少握住一根绳子,它就不会飘走。皮带/气球类比也擅长让人们忘记“所有权”是由保留/释放管理的。
m
mattjgalloway

这两个定义不是相同的。

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

考虑以下:

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

现在我们有两个指向 <some_object> 的指针,一个是强的,一个是弱的。如果我们像这样将 strongObject 设置为 nil

strongObject = nil;

然后,如果您仔细阅读您概述的规则,那么您会问自己以下问题:

强:“将其保留在堆中,直到我不再指向它为止” strongObject 不再指向 。所以我们不需要保留它。弱:“只要其他人强烈指向它就保持这个”弱对象仍然指向 。但是由于没有其他人指出它,这条规则也意味着我们不需要保留它。

结果是 <some_object> 被解除分配,如果您的运行时支持它(Lion 和 iOS 5 以上),那么 weakObject 将自动设置为 nil

现在考虑如果我们像这样将 weakObject 设置为 nil 会发生什么:

weakObject = nil;

然后,如果您仔细阅读您概述的规则,那么您会问自己以下问题:

强:“将它保留在堆中,直到我不再指向它”strongObject 确实指向 。所以我们确实需要保留它。弱:“只要其他人强烈指向它,就保持它”弱对象不指向

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

[请注意,所有假设 <some_object> 都没有被其他地方的另一个强引用/其他一些被“持有”的方式指向]


所以强和弱之间的主要区别在于,强指向的对象的释放将自动清除所有相关的弱指针。而对于指向某物的弱指针,总是存在一个强指针。如果是这样,主要的应用程序对象必须被强烈指向?
对于指向 valid 的弱指针,那么是的,必须有一个强指针。再加上 iOS 5 和 Lion 支持自动剔除弱引用的事实,你就会得到你所说的。不过,iOS 4 的运行时 支持这一点。我假设您的“主要应用程序对象”是指 UIApplication 对象?这将被 UIKit 的内部工作强烈引用 - 但您不必担心这一点。
我认为您可以使用“strongObjectPointer”之类的词而不是“strongObject”。所以编程新手会有更好的意义。 @BJ Homer 在 Mr.Matt.Interesting 的帖子中很受欢迎:)
S
Shashi3456643

强的

在财产和分配的价值之间建立所有权。这是 ARC 中对象属性的默认设置,因此它不会让您担心引用计数并自动释放引用。它是保留的替代品。当且仅当我们需要用作保留时,我们才使用。

虚弱的

在财产和分配的价值之间创建非所有权。 Strong 用于父对象,weak 用于释放父对象时的子对象,然后子对象引用也设置为 nil 它有助于防止保留循环。垃圾收集器收集时它不保护引用的对象。弱本质上是分配的,不保留的财产。


值得一提的是,保留周期通常是什么。我们有两个对象:对象 A 和对象 B。对象 A 对对象 B 具有强引用,对象 B 对对象 A 具有强引用。没有其他对象对对象 A 或 B 具有强引用。
R
RobotCharlie

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


G
Gabriel

不,它们并不相同,但非常不同。只有在需要保留对象时才使用 strong 。在任何其他情况下都使用弱,其优点是您可以知道对象是否已从堆中删除,因为没有人保留它。


P
Peter Wone

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

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

[SC 意味着] ...任何执行的结果都与所有处理器的操作都按某种顺序执行的结果相同,并且每个单独的处理器的操作按照其程序指定的顺序出现在该顺序中。 - 兰波特,1979

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

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

虽然 Arm8+ 确实通过对获取/发布的明确支持彻底改变了这一点,但旧版软件不使用这种支持。旧版软件包括所有三个手机操作系统及其上运行的所有内容,以及编译器和库,直到它们被更新。

对于这个主题的扩展检查,我建议您参考无与伦比的 Herb Sutter