在重新启动应用程序后,containsObject返回NO

时间:2016-05-12 19:27:54

标签: ios objective-c nsmutablearray nsarray nsdictionary

我有一个显示项目列表的UITabelView(从服务器返回),用户可以选择任何项目并将其添加到他自己的部分。 在选择项目时,我正在检索所选项目详细信息并将其保存到pList文件,然后该列表将显示一个小图标,通知用户该项目已添加到他的部分。用户可以通过再次点击图标将其从部分中删除。

要知道该项目是否已经在他的部分中,我正在使用

[self.myItemsArray containsObject:item]

如果用户不退出应用程序,一切都很完美。重新启动应用后,问题就出现了。当我从数据库或服务器检索tableview列表时,所有项目都不会显示在我的列表中,[self.myItemsArray containsObject:item]将为之前添加的项目返回NO。

我正在寻找另一种方法,通过创建我的项目ID的NSArray,然后检查新数组是否包含项目ID以显示图标。 新问题是id从服务器返回为double并按原样存储。创建数组时应用程序崩溃:

[self.myItemsArray valueForKey:@"Id"]

myItemsArray是一个项目数组(item是包含所有细节的NSDictionary)

所以我现在很绝望,任何人都可以通过解决上述任何问题来帮助我吗? 我更喜欢第一个,因为containsObject会更简单,但我不介意用第二个选择解决它,如果第一个不起作用。

1 个答案:

答案 0 :(得分:1)

您需要确保为自定义类定义了良好的isEqual:方法,因为这是NSArray用于确定遏制的方法:https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/#//apple_ref/occ/instm/NSArray/containsObject

假设这个类有类似'key'或'id'的值,对于每个类的实例(在你的情况下是double类型)是唯一的。当然,情况并非总是如此;它通常是个别属性/ ivars的集合,构成一个独特的“关键”,但为了讨论的目的,让我们说这样一个领域存在。您的代码可能看起来像这样(全部在.m中):

static double const EPSILON = .000000001; // You'll need to be the judge of how "close" values can be to each other but still be distinct

@interface MyObjectClass: NSObject
@property (nonatomic, readonly) double uniqueKey;
@end

@implementation MyObjectClass

// ...

- (BOOL)isEqual:(id)object
{
    if (self == object) { return YES; }
    if (!object isKindOfClass:[MyObjectClass class]]) { return NO; }

    MyObjectClass *myObject = (MyObjectClass *)object;
    if (abs(self.uniqueKey - myObject.uniqueKey) < EPSILON) { return YES; }
    return NO;
}

//...

@end

请注意,您应检查两个floatdouble值之间的直接相等性;请参阅How dangerous is it to compare floating point values?,了解有关使用浮点和双精度值的陷阱的详细讨论。