代码之家  ›  专栏  ›  技术社区  ›  mrueg

NSManagedObject作为NSDictionary密钥?

  •  18
  • mrueg  · 技术社区  · 17 年前

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

    然而,问题是 被管理对象 NSCopying 协议,这意味着没有 被管理对象 可以用作字典键,即使 -[hash] 这种方法对他们很有效。

    4 回复  |  直到 14 年前
        1
  •  33
  •   Mike Abdullah    11 年前

    有四种选择:

    1. [object objectID] 或 +[NSValue valueWithNonretainedObject:] 似乎最明显
    2. 使用 CFDictionaryCreateMutable() 使用创建词典的步骤 保留 键,而不是复制,而是,然后调用 CFDictionarySetValue() 存储对象
    3. 在OS X或iOS6+上, [NSMapTable mapTableWithStrongToStrongObjects] 给你一个纯Objective-C等价于 CFMutableDictionary
    4. 使生效 NSCopying 对于托管对象子类,这样它将返回self(如果不使用ARC,则带有一个颠簸引用计数)

    笔记

    +valueWithNonretainedObject: 这是相当危险的,因为它有可能被留下一个悬空的指针;可能是最好避免的。

    存储对象ID很好,除了 刚出现的 物体的生命起源于 短暂的 ID。当上下文保存到磁盘时,该ID将更改为永久ID(或 -obtainPermanentIDsForObjects:… 被称为)。您的映射代码需要足够智能才能处理此问题,除非它可以保证所有传入对象都已经有一个永久ID。

    实施 复制 这样感觉有点恶心,但应该很好用。碰巧的是,这正是方法 NSURLSessionTask 我想,这是因为词典的友好性。

    在OSX10.8MountainLion之前,通常可以创建一个常规的 NSMutableDictionary 然后打电话 CFDictionarySetValue() 为了它。不过,情况已经不是这样了;新字典现在在CF级别指定了正确的副本回调,而不仅仅是 易变词典

        2
  •  1
  •   czizzy    17 年前

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

        3
  •  0
  •   Tom Jefferys    17 年前

        4
  •  0
  •   David Ben Yosef    13 年前

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

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

    出于上述原因,这不起作用(不复制),所以我做了:

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

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