2

简短:
我需要通过一个键找到核心数据对象,该键包含任意对象的唯一不可变数组(固定长度,但在运行时选择)(不仅元素成员资格,而且元素顺序决定唯一性)。然而NSManagedObject禁止覆盖 [isEqual:]. 怎么办?


Long:
我的核心数据模型中有一个实体(参见实体“...链接”的图表图像),我必须根据属性键(“元组”)保证其唯一性。到现在为止还挺好。

然而,实体的唯一属性必须是NSArray
为了让事情变得更加困难,我既不知道元组元素类类型。 我也不知道元组的元素数。好吧,实际上每个元组(至少每个核心数据上下文)的计数都是相同的,但在应用程序运行之前不知道。

我的链接实体必须只有一个实例与给定的 tuple
并且出于显而易见的原因,只有一个元组实例具有给定的任意对象数组。而如果返回
,则两个元组将被视为相等。 NSManagedObject 禁止覆盖and ,否则事情将是小菜一碟。[tuple_1 isEqual:tuple_n]YES[isEqual:][hash]

“…Tuple”对象与它们的标记数组一起创建(通过一种方便的方法)并且是不可变的(每个“…Token”及其数据属性也是如此)。(将“…Tuple”想象成“…Link”的字典键。)

"...Tuple" 实现"- (NSArray *)tokens;",它根据 "...TokenOrder" 的 "order" 键返回一个整齐有序的令牌数组。元组预计最多包含 5 个元素。)

然而,我希望有数万个(在某些极端情况下可能更多)“...Link”对象,我必须(经常)根据它们的“元组”属性找到它们

可悲的是,我在任何文献或网络上都找不到任何关于这种情况的文章(更不用说解决方案了)。

有任何想法吗?

核心数据模型

到目前为止,我提出的一个可能的解决方案是:

  1. 通过向“…Tuple”添加另一个名为“ tupleHash”的属性来按元组进行比较的元素数量较少,该属性是通过以下方式在对象创建时预先计算的:片段 1

  2. 使用 NSPredicate 查询匹配 tupleHash 的对象(缩小候选列表相当多)。

  3. 在缩小的候选列表中查找具有给定元组的“…链接”:片段 1

片段1:

NSUInteger tupleHash = [[self class] hash];
for (id token in self.tokens) {
    tupleHash ^= [token.data hash];
}

片段 2:

__block NSArray *tupleTokens = someTokens;
NSArray *filteredEntries = [narrowedCandidates filteredArrayUsingPredicate:
  [NSPredicate predicateWithBlock: ^(id evaluatedObject, NSDictionary *bindings) {
    return [evaluatedObject.tuple.tokens isEqualToArray:tupleTokens];
}]];

(抱歉,markdown 似乎反对将列表与代码片段混合。)

好主意还是只是疯了?

提前致谢!

4

2 回答 2

1

我强烈建议您计算对象的哈希值并将其存储在数据库中。你的第二个片段会严重影响性能,这是肯定的。

更新:

你不需要使用 NSArray 的 hash 方法。要计算哈希,您可以对数组值执行 SHA1 或 MD5,并连接。散列算法有很多种,这里只有两种。

您可以为 NSArray 创建一个类别,例如myHash使代码可重用。

于 2011-01-17T16:12:26.103 回答
0

正如Joe Blow在评论中所建议的那样,我将使用 SQLite。Core Data 在这里似乎是错误的工具。

好处:

  • 得益于 SQL 的列索引,速度很快
  • 在返回结果之前,SELECT 上没有对象分配/初始化。(Core Data 需要进行属性检查)
  • 使用 JOIN 轻松查询链接元组。
  • 轻松使用 SQLite 的 JOIN、GROUP BY、ORDER BY 等
  • 由于EGODatabase受 FMDB 启发的 SQLite Objective-C 包装器) ,几乎没有包装器代码
于 2011-01-19T01:04:05.917 回答