【发布时间】:2010-12-02 15:04:40
【问题描述】:
在我的应用程序中,我有一个NSDictionary,其键应该是NSManagedObject 的子类的实例。
然而,问题是NSManagedObject 没有实现NSCopying 协议,这意味着即使-[hash] 方法适用于他们。
我应该这样做吗?
【问题讨论】:
标签: cocoa core-data nsdictionary nscopying
在我的应用程序中,我有一个NSDictionary,其键应该是NSManagedObject 的子类的实例。
然而,问题是NSManagedObject 没有实现NSCopying 协议,这意味着即使-[hash] 方法适用于他们。
我应该这样做吗?
【问题讨论】:
标签: cocoa core-data nsdictionary nscopying
有四个选项:
[object objectID] 或 +[NSValue valueWithNonretainedObject:] 似乎是最明显的CFDictionaryCreateMutable()创建一个带有保留键的字典,而不是复制,然后调用CFDictionarySetValue()来存储对象[NSMapTable mapTableWithStrongToStrongObjects] 为您提供与 CFMutableDictionary 等效的纯 Objective-C
NSCopying,使其返回 self(如果您不使用 ARC,则引用计数会增加)+valueWithNonretainedObject: 非常危险,因为它可能会留下一个悬空指针;最好避免。
存储对象 ID 很好,除了 new 对象以 临时 ID 开始生命。然后,当上下文保存到磁盘(或调用 -obtainPermanentIDsForObjects:…)时,该 ID 将更改为永久 ID。您的映射代码需要足够聪明才能处理这个问题,除非它可以保证所有传入的对象都已经有一个永久 ID。
像这样实现NSCopying 感觉有点恶心,但应该可以正常工作。碰巧,这正是NSURLSessionTask 采用的方法,我认为是为了字典友好。
在 OS X 10.8 Mountain Lion 之前,曾经可以创建一个常规的NSMutableDictionary,然后为它调用CFDictionarySetValue()。但情况已不再如此。新字典现在在 CF 级别向下指定了正确的复制回调,而不是纯粹是 NSMutableDictionary 的一个功能。
【讨论】:
我建议使用 [[[myManagedObject objectID] URIRepresentation] absoluteString] 作为您的密钥。
【讨论】:
您能否创建一个包装类,其中包含对您想用作字典键的 NSManagedObject 实例的引用?然后,您可以让这个包装类实现 NSCopying,以及一个散列方法(可能只是调用 NSManagedObject 的散列方法),并将这个包装类用作字典键。
【讨论】:
我遇到了类似的问题,我需要将多个实体与每个实体的附加数据捆绑在一起,最初尝试过:
@{entity1:data1, @entity2:data2, @entity3:data3}
由于上述原因(NSCopying),这不起作用,所以我做了:
@[
@{@"entity":entity1, @"data":data1},
@{@"entity":entity2, @"data":data2},
@{@"entity":entity3, @"data":data3}
]
但只有当您不需要对这些实体进行字典式访问或乐于迭代以找到所需内容时,此解决方案才有意义。就我而言,这是一个包装问题。请注意,如果您在 NSManagedObjectContext 周围传递这些实体,则需要相同才能使用它们。
【讨论】: