核心数据。使用常量文字作为属性名称的NSPredicate问题

时间:2014-05-05 13:36:25

标签: ios core-data nspredicate

我有NSManagedObject属性。假设它是一个属性:

@property (retain, nonatomic) NSString *city;

为了从核心数据中获取数据,我总是使用NSPredicate。谓词如下所示:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"city", @"San Francisco"];

但问题是项目使用密钥" city"作为未定义的关键词,意思是常量。所以我们假设我使用密钥" city"在我的应用程序1000次,所以如果NSManagedObject的属性被更改,我需要用新的键替换所有这些键,例如,到cityName。在这种情况下,我需要使用谓词:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"cityName", @"San Francisco"];

不舒服。所以现在我正在使用全局extern NSString key kCity = @"city";,但如果数据模型也发生了变化,那么就会出现问题,因为如果属性发生变化,我只会在运行应用程序时出现崩溃,而控制台会说我:

'key path city not found in entity <NSSQLEntity...

哪种解决方法可以在这里?我想过用

之类的东西
NSString * const kCity = myEntity.city.propertyString;

因此,如果属性被更改,那么解析器将告诉我项目有错误,我无法运行应用程序。因此,在我将属性更改为常量后,我将能够运行应用程序

如何获取NSString中的属性名称。当然这只是建议,也许有人有另一种变体。

由于

2 个答案:

答案 0 :(得分:2)

您可以使用mogenerator,它所做的一件事就是为您可以使用的属性和关系键创建struct

// .h
extern const struct MBListAttributes {
    __unsafe_unretained NSString *title;
} MBListAttributes;

// .m
const struct MBListAttributes MBListAttributes = {
    .title = @"title",
};

然后,您可以使用MBListAttributes.title来获取正确的密钥。

答案 1 :(得分:0)

当我想要一个键的名称时,我使用this基于宏的解决方案来避免字符串文字。

它允许您以这种方式编写密钥名称:

[NSPredicate predicateWithFormat:@"%K = %@", Key(YourManagedObjectSubclass, propertyName), @"aValue"];

编译器将检查YourManagedObjectSubclass是否具有给定名称的属性。

但是,当然,请记住,如果更改数据模型中的属性名称,仍需要在NSManagedObject子类中更改它。