【问题标题】:Do I need to release a copied NSObjects - Objective-c我是否需要发布复制的 NSObjects - Objective-c
【发布时间】:2011-01-26 15:47:37
【问题描述】:

我想知道我是否需要释放一个复制的 NSObject?例如,我只创建一个字典并将其复制到一个数组中:

代码:

for (int num = 0; num < [object count]; num++) {
    [dictionary setObject:[object objectAtIndex:num] forKey:@"x"];
    [array addObject:[dictionary copy]];
}

我必须释放字典吗?如果有,什么时候?

谢谢

【问题讨论】:

  • 根据经验,在 Cocoa 中你必须释放你拥有的任何东西。如果您使用 new、copy、alloc 或 retain 向它发送消息,您就拥有了它。如果您没有调用这些方法之一,则您不拥有它,也不应该释放它。

标签: iphone objective-c cocoa memory-management copy


【解决方案1】:

如果不查看您在哪里创建字典,就很难判断这是否明智。如果字典中没有其他成员,那么做类似的事情会更简单(虽然可以说更难阅读:)

for (int num = 0; num < [object count]; num++) {
    [array addObject:[NSDictionary
                           dictionaryWithObject:[object objectAtIndex:num]
                                        forKey:@"x"
                     ]
    ]
}

这将在您的数组中为您提供真正的 NSDictionary 对象,而不是您正在创建的 NSMutableDictionary 副本。

【讨论】:

  • 您基于什么理由声称 NSMutableDictionary 的副本不会是“真正的 NSDictionary”?
  • 基于一个真正的 NSDictionary 如果你尝试插入对象会抛出错误。
【解决方案2】:

使用copy,您获得了返回对象的所有权。容器还拥有添加到它们的对象的所有权。
结果,正如诺亚指出的那样,您必须放弃副本的所有权。 Cocoa memory management guidelines 包含一个注释 how to work with containers 的部分。

【讨论】:

    【解决方案3】:

    文档中的这个片段:

    - (id)copy

    返回值 NSCopying 协议方法 copyWithZone: 返回的对象,其中 zone 为 nil。

    讨论 对于采用 NSCopying 协议的类来说,这是一种方便的方法。如果没有 copyWithZone: 的实现,则会引发异常。

    NSObject 本身不支持 NSCopying 协议。子类必须支持该协议并实现 copyWithZone: 方法。 copyWithZone: 方法的子类版本应该首先向 super 发送消息,以合并其实现,除非子类直接来自 NSObject。

    特殊注意事项 如果您使用托管内存(不是垃圾回收),此方法会在返回新对象之前保留它。 然而,方法的调用者负责释放返回的对象。

    【讨论】:

      【解决方案4】:

      是的,你知道。在这种情况下,您应该在将副本添加到数组后立即释放副本,因为数组会保留添加到其中的任何内容:

       NSDictionary *copied = [dictionary copy];
       [array addObject:copied];
       [copied release];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-28
        相关资源
        最近更新 更多