【问题标题】:Explanation of strong and weak storage in iOS5iOS5中强弱存储的解释
【发布时间】:2012-03-04 23:22:16
【问题描述】:

我是 iOS5 开发和使用 Objective-c 的新手。我无法理解 strongweak 存储之间的区别。我已经阅读了文档和其他 SO 问题,但它们听起来和我一模一样,没有进一步的见解。

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

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

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

【问题讨论】:

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

标签: memory-management ios5 automatic-ref-counting


【解决方案1】:

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

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

[SC 表示]...任何执行的结果都与所有的操作相同 处理器以某种顺序执行,并且 每个单独的处理器的操作出现在这个序列中 程序指定的顺序。 - Lamport, 1979

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

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      强大

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

      1. 在财产和指定价值之间创建非所有权。
      2. 当释放父对象时,对父对象使用强,对子对象使用弱,然后子对象引用也设置为 nil
      3. 它有助于防止保留循环。
      4. 垃圾回收器回收时不保护引用的对象。
      5. Weak 本质上是分配的,不保留的属性。

      【讨论】:

      • 这里值得一提的是保留周期通常是什么。我们有两个对象:对象 A 和对象 B。对象 A 对对象 B 有强引用,对象 B 对对象 A 有强引用。没有其他对象对对象 A 或 B 有强引用。
      【解决方案4】:

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

      也许可以举个例子。

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

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

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

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

      【讨论】:

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

      这两个定义不一样吗?

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

      考虑以下几点:

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

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

      strongObject = nil;
      

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

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

        strongObject 不再指向&lt;some_object&gt;。所以我们不需要保留它。

      2. Weak:“只要其他人强烈指向它,就保持这个”

        weakObject 仍然指向&lt;some_object&gt;。但是由于没有else指向它,这条规则也意味着我们不需要保留它。

      结果是&lt;some_object&gt; 被释放,如果您的运行时支持它(Lion 和 iOS 5 以上),那么weakObject 将自动设置为nil

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

      weakObject = nil;
      

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

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

        strongObject 确实指向 &lt;some_object&gt;。所以我们确实需要保留它。

      2. Weak:“只要其他人强烈指向它,就保持这个”

        weakObject 不指向&lt;some_object&gt;

      结果是&lt;some_object&gt;没有被释放,但weakObject 将是nil 指针。

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

      【讨论】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-08
        • 2013-12-12
        • 1970-01-01
        • 1970-01-01
        • 2013-05-06
        • 2015-02-25
        • 1970-01-01
        相关资源
        最近更新 更多