【问题标题】:what's the difference between two code scenario两个代码场景有什么区别
【发布时间】:2011-08-04 02:39:33
【问题描述】:

场景1:

NSDictionary *dictionary =
              [[NSDictionary alloc] initWithContentsOfFile:plistPath];
self.stateZips = dictionary;
[dictionary release];

场景2:

self.stateZips = [[NSDictionary alloc] initWithContentsOfFile:plistPath];

【问题讨论】:

    标签: objective-c memory-management


    【解决方案1】:

    取决于stateZips 属性。
    如果是retained:
    场景 1:stateZips 被正确保留(stateZips 上的发布将调用它的 dealloc)。当地词典也随即发布。
    场景 2:stateZips 被保留两次(stateZips 中的发布不会调用它的 dealloc,因为它仍然被保留)。

    如果是assigned:
    场景 1:stateZips 指向已发布的字典并在其他可能导致崩溃的地方访问它。
    场景 2:stateZips 被正确保留(stateZips 上的发布将调用它的 dealloc)。

    copy 没有被考虑,因为我相信这不是你的意图(至少在这段代码中)

    【讨论】:

    • 对不起 Tatvamasi,我发布我的问题时没有看到您的问题。它们非常相似;我赞成你的投票,但我也会离开我的,因为看起来有一些不同。
    【解决方案2】:

    两者都导致 self.stateZips 被设置为使用 plistPath 中指向的文件初始化的字典。

    但是在第二个中,指向初始化字典的指针没有保存,因为它是一个保留计数为 +1 的对象,技术上需要在某个地方向它发送 release 消息,以平衡内存管理。但由于无法检索指向该对象的指针,最终会导致内存泄漏。

    有两个例外:

    1.垃圾回收
    如果您处于垃圾收集环境中,则两者都是相同的。嗯,它们不一样,但结果是相似的。

    2.属性类型
    如果stateZips 的设置器只是分配指针,那么您可以使用 ivar 指针释放对象。那么这两段代码只有一个区别:在前者中,对象在使用后立即释放。在后者中,它只是“未定义”。没有上下文,很难确定这个对象是否被释放,以及何时释放。

    【讨论】:

    • 这真的正确吗?当然编译器可以优化它,以便只调用一个保留?在我读过的关于 Objective-c 内存管理的所有内容中——我从未见过场景 2 的示例是泄漏。
    • Scenario2 如果该属性保留则泄漏。
    【解决方案3】:

    我假设 stateZips 是一个具有 retain 属性的属性。

    在场景 1 中。在第一行创建了一个保留计数为 1 的字典。在第二行中,该属性将再次调用retain,将保留计数增加到2。最后,保留计数因释放而减少。这将使字典具有正确的保留计数。

    在场景 2 中,retain 只被调用一次。

    这两种情况的最终效果是相同的。字典对象将被保留,您需要在类的 dealloc 方法中包含一个释放。

    如果编译器没有正确处理这个问题,那么确实很难遵循objective-c的保留/释放规则。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-06
      • 2020-03-29
      相关资源
      最近更新 更多