在我的应用中,我有一个NSDictionary
,其键应该是NSManagedObject
子类的实例。
然而,问题是NSManagedObject
没有实现NSCopying
协议,这意味着即使NSManagedObject
也没有核心数据对象/ -[hash]
实例可以用作字典键。 {1}}方法适用于他们。
我该怎么办?
答案 0 :(得分:32)
有四种选择:
[object objectID]
似乎是最明显的+[NSValue valueWithNonretainedObject:]
创建一个包含保留键的字典,而不是复制,然后调用CFDictionaryCreateMutable()
来存储对象CFDictionarySetValue()
为您提供与[NSMapTable mapTableWithStrongToStrongObjects]
相当的纯粹Objective-C CFMutableDictionary
,以便它返回self(如果您不使用ARC,则会使用引用次数增加) NSCopying
非常危险,因为可能会留下一个悬垂的指针;最好避免。
存储对象ID很好,除了 new 对象以临时 ID开始生命的事实。当上下文保存到磁盘(或调用+valueWithNonretainedObject:
)时,该ID将更改为永久ID。您的映射代码必须足够智能才能处理此问题,除非它可以保证所有传入的对象都具有永久ID。
像这样实现-obtainPermanentIDsForObjects:…
感觉有点icky,但应该工作得很好。碰巧,这正是NSCopying
所采用的方法,我认为字典友好。
在OS X 10.8 Mountain Lion之前,过去可以创建常规NSURLSessionTask
,然后为其调用NSMutableDictionary
。但事实并非如此;新词典现在具有在CF级别指定的适当复制回调,而不是纯粹是CFDictionarySetValue()
的功能。
答案 1 :(得分:0)
您是否可以创建一个包装类,它包含对要用作字典键的NSManagedObject实例的引用?然后,您可以使此包装类实现NSCopying,以及哈希方法(可能只是调用NSManagedObject的哈希方法),并使用此包装器作为字典键。
答案 2 :(得分:0)
我建议使用[[[myManagedObject objectID] URIRepresentation] absoluteString]作为你的密钥。
答案 3 :(得分:0)
我遇到了类似的问题,我需要将几个实体与每个实体捆绑在一起,最初尝试:
@{entity1:data1, @entity2:data2, @entity3:data3}
这不适用于上述原因(NSCopying),所以我做了:
@[
@{@"entity":entity1, @"data":data1},
@{@"entity":entity2, @"data":data2},
@{@"entity":entity3, @"data":data3}
]
但是,只有当您不需要对这些实体进行字典样式访问或者很乐意迭代以找到所需内容时,此解决方案才有意义。就我而言,这是一个包装问题。请注意,如果您在NSManagedObjectContext周围传递这些实体,则需要使用它们。