NSManagedObject 作为 NSDictionary 键?

发布于 2024-08-06 20:26:31 字数 243 浏览 7 评论 0原文

在我的应用程序中,我有一个 NSDictionary,其键应该是 NSManagedObject 子类的实例。

然而,问题在于 NSManagedObject 没有实现 NSCopying 协议,这意味着 NSManagedObject 的核心数据对象/实例不能用作字典键,即使 -[hash] 方法对它们来说效果很好。

我应该做什么?

In my app, I have a NSDictionary whose keys should be instances of a subclass of NSManagedObject.

The problem, however, is that NSManagedObject does not implement the NSCopying protocol which means that no Core Data objects / instances of NSManagedObject can be used as dictionary keys even though the -[hash] method works fine for them.

Was should I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

贩梦商人 2024-08-13 20:26:31

有四个选项:

  1. 使用不同的对象作为字典键,然后从中查找。 [object objectID]+[NSValue valueWithNonretainedObject:] 似乎是最明显的
  2. 使用 CFDictionaryCreateMutable() 创建一个带有 retained< 的字典/em> 键,而不是复制,然后调用 CFDictionarySetValue() 来存储对象
  3. 在 OS X 或 iOS6+ 上,[NSMapTable mapTableWithStrongToStrongObjects] 为您提供纯粹的 Objective -C 相当于 CFMutableDictionary
  4. 为您的托管对象子类实现 NSCopying,以便它返回 self(如果您不使用 ARC,则具有增加的引用

计数

) +valueWithNonretainedObject: 非常危险,因为可能会留下悬空指针;可能最好避免。

存储对象 ID 很好,除了对象以临时 ID 开始生命这一事实之外。当上下文保存到磁盘时(或调用 -obtainPermanentIDsForObjects:... ),该 ID 将更改为永久 ID。您的映射代码需要足够智能才能处理此问题,除非它可以保证所有传入对象都已经具有永久 ID。

像这样实现 NSCopying 感觉有点恶心,但应该可以正常工作。碰巧,这正是 NSURLSessionTask 所采用的方法,我认为是为了字典友好性。

在 OS X 10.8 Mountain Lion 之前,可以创建常规 NSMutableDictionary,然后为其调用 CFDictionarySetValue()。但现在情况不再是这样了;新字典现在在 CF 级别指定了正确的复制回调,而不是纯粹是 NSMutableDictionary 的一个功能。

There are four options:

  1. Use a different object as the dictionary key instead, and lookup from that. [object objectID] or +[NSValue valueWithNonretainedObject:] seem the most obvious
  2. Use CFDictionaryCreateMutable() to create a dictionary with retained keys, rather than copied, instead, and then call CFDictionarySetValue() to store the objects
  3. On OS X or iOS6+, [NSMapTable mapTableWithStrongToStrongObjects] gives you a purely Objective-C equivalent to CFMutableDictionary
  4. Implement NSCopying for your managed object subclass, such that it returns self (with a bumped reference count if you're not using ARC)

Notes

+valueWithNonretainedObject: is pretty dangerous, since it's possible to be left with a dangling pointer; likely best to avoid.

Storing object IDs is fine, apart from the fact that new objects start out life with a temporary ID. That ID then changes to a permanent one when the context is saved to disk (or -obtainPermanentIDsForObjects:… is called). Your mapping code needs to be smart enough to handle this unless it can guarantee that all incoming objects already have a permanent ID.

Implementing NSCopying like this feels a bit icky, but should work just fine. As it happens, this is exactly the approach NSURLSessionTask takes, I presume for dictionary friendliness.

Prior to OS X 10.8 Mountain Lion, it used to be possible to create a regular NSMutableDictionary and then call CFDictionarySetValue() for it. That's no longer the case though; new dictionaries now have proper copy callbacks specified down at the CF level, rather than purely being a feature of NSMutableDictionary.

故事↓在人 2024-08-13 20:26:31

我建议使用 [[[myManagedObject objectID] URIRepresentation]absoluteString] 作为密钥。

I suggest to use [[[myManagedObject objectID] URIRepresentation] absoluteString] as your key.

你如我软肋 2024-08-13 20:26:31

您可以创建一个包装类,其中包含对要用作字典键的 NSManagedObject 实例的引用吗?然后,您可以使此包装器类实现 NSCopying 以及哈希方法(可能只是调用 NSManagedObject 的哈希方法),并使用此包装器作为字典键。

Could you create a wrapper class, that contains a reference to the instance of NSManagedObject that you want to use as a dictionary key? You could then make this wrapper class implement NSCopying, along with a hash method (perhaps just calling the NSManagedObject's hash method), and use this wrapper as the dictionary key.

£烟消云散 2024-08-13 20:26:31

我遇到了类似的问题,其中我需要将多个实体与每个实体的附加数据捆绑在一起,并最初尝试:

@{entity1:data1, @entity2:data2, @entity3:data3}

由于上述原因(NSCopying),这不起作用,所以我这样做了:

@[
   @{@"entity":entity1, @"data":data1},
   @{@"entity":entity2, @"data":data2},
   @{@"entity":entity3, @"data":data3}
]

但只有当您不这样做时,这个解决方案才有意义不需要以字典方式访问这些实体,或者很乐意迭代以找到您需要的内容。就我而言,这是一个包装问题。请注意,如果您在 NSManagedObjectContext 周围传递这些实体,则需要相同才能使用它们。

I had a similar problem, in which I needed to bundle several entities with additional data for each, and initially tried:

@{entity1:data1, @entity2:data2, @entity3:data3}

this didn't work for the reason above (NSCopying), so I did:

@[
   @{@"entity":entity1, @"data":data1},
   @{@"entity":entity2, @"data":data2},
   @{@"entity":entity3, @"data":data3}
]

But this solution makes sense only if you don't need dictionary style access to these entities or are happy to iterate to find what you need. In my case this was a packaging problem. Note that if you pass these entities around the NSManagedObjectContext need to be the same to use them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文