对数组对象正确测试对象相等性的最佳方法是什么?

时间:2010-03-12 15:24:34

标签: iphone

我的目标是在解析缓存中已存在的项时中止NSXMLParser。该程序的基本流程如下:

1)程序启动并下载XML Feed。 Feed中的每个项目都由自定义对象(FeedItem)表示。每个FeedItem都会添加到一个数组中。

2)解析完成后,数组的内容(所有FeedItem对象)将存档到磁盘。

下次执行程序或用户刷新Feed时,我再次开始解析;但是,由于现在存在一个缓存(数组),因为每个项都被解析,我想看看该对象是否存在于缓存中。如果确实如此,我知道我已经下载了所有新项目,不再需要继续解析。

我想,我正在学习的是,我不能使用indexOfObject或indexOfObjectIDenticalTo:因为这些实际上似乎正在检查对象是否使用相同的内存地址(因此相同)。

我想要做的是查看对象的内容是否相等(或至少是某些内容)。我做了一些研究,发现我可以覆盖IsEqual方法;但是,我真的不想为每个新解析的XML FeedItem迭代/枚举整个缓存内容表。是否正在迭代整个集合并测试每个集合的平等,这是实现这一目标的唯一方法,还是有一种我不了解的更好的技术?

目前我使用以下代码,但我知道需要更改:
    NSUInteger index = [self.feedListCache.feedList indexOfObject:self.currentFeedItem];     if(index == NSNotFound){     }

1 个答案:

答案 0 :(得分:1)

作为替代方案,也许你也可以维护一个项目字典。 IIRC,RSS和Atom都指定每个项目都有一个唯一的密钥(或者只是一个链接,在RSS的情况下?)。如果您使用这些唯一标识符作为字典键,则可以快速确定您是否已经看到与您刚解析的项目相匹配的项目。

所以,在伪代码中,它可能会像这样工作:

FeedItem* item;
NSMutableArray* allItems;
NSMutableDictionary* itemIndex;

// if this is not the first run, load existing stuff into allItems and itemIndex
// set up the parser

while( item = [parser nextItem] ) {
  FeedItem* existingItem = [itemIndex objectForKey:[item uniqueKey]];
  if( existingItem == nil ) {
    // haven't seen this item before
    [allItems addObject:item];
    [itemIndex setObject:item forKey:[item uniqueKey]];
  }
  else {
    // done parsing
    break;
  }
}

// clean up parser, save items to disk, etc.

警告:有人可以更新Feed中的项目(例如,在发布后更改标题)。因此,当您看到之前看过的项目时,您可能不一定想要停止解析。以上对我的建议的一个改进可能是比较缓存项目的发布日期和新解析的项目。 (但即便如此也不是万无一失。)