首页 文章

iOS5中强弱存储的说明

提问于
浏览
111

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

我读了the documentation: Transitioning To ARC - 它引用了iOS4的retain,assign和release术语;这让我很困惑 . 然后我看看Open U CS193p,它区分强弱:

坚强:“把它放在堆里直到我不再指向它了”弱点:“只要别人强烈指出它就保持这个”

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

6 回答

  • 1

    这两个定义不是一样的 .

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

    考虑以下:

    __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 设置为 nil 会发生什么:

    weakObject = nil;
    

    然后,如果你遵守你概述的规则,那么你会问自己这些问题:

    • 强:“把它放在堆里直到我不再指向它了”

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

    • 弱:“只要别人强烈指出它就保持这个”

    weakObject 未指向 <some_object> .

    结果是 <some_object> 未被释放,但 weakObject 将是 nil 指针 .

    [注意,假设 <some_object> 的所有内容都没有被其他地方的其他强引用指向/其他一些方法"held"]

  • 502

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

    也许一个例子是有序的 .

    想象一下,我们的对象是一只狗,狗想要逃跑(被解除分配) .

    强壮的指针就像是狗的皮带 . 只要你的皮带附着在狗身上,狗就不会逃跑 . 如果五个人将他们的皮带连接到一只狗,(五个强指针指向一个物体),那么在所有五个皮带脱落之前,狗不会逃跑 .

    另一方面,弱点就像小孩子指着那只狗说“看!一只狗!”只要狗仍然在皮带上,小孩子仍然可以看到狗,他们仍然会指向它 . 然而,一旦所有的皮带脱落,无论有多少小孩指着它,狗都会逃跑 .

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

  • 34

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

  • 2

    我知道我参加这个派对已经很晚了,但我认为通过指出“强弱记忆模型”的含义取决于你是在谈论软件还是硬件来混淆这个问题是很重要的 .

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

    [SC表示] ......任何执行的结果都与所有处理器的操作按某种顺序执行相同,并且每个处理器的操作按照其程序指定的顺序显示在此序列中 . - Lamport,1979

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

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

    虽然Arm8确实在明确支持获取/发布的情况下完全改变了这一点,但遗留软件并未使用此支持 . 传统软件包括所有三个手机操作系统及其上运行的所有内容,以及编译器和库,直到它们更新为止 .

    有关此主题的扩展检查,我建议您使用无与伦比的Herb Sutter .

  • 2

    不,他们并不完全相同但却截然不同 . 仅在需要保留对象时才使用strong . 你在任何其他情况下使用弱,你可以知道是否已经从堆中删除了对象,因为没有人保留它 .

  • 1

    强大

    • 在属性和指定值之间创建所有权 .

    • 这是ARC中对象属性的默认值,因此它不会让您担心引用计数并自动释放引用 .

    • 这是保留的替代品 . 当且仅当我们需要使用保留时,我们使用 .

    • 在属性和指定值之间创建非所有权 .

    • 在父对象上使用Strong,在释放父对象时在子对象上使用weak,然后子对象引用也设置为nil

    • 它有助于防止保留周期 .

    • 由垃圾收集器收集时,它不保护引用的对象 .

    • 弱基本上被分配,未获得 property .

相关问题