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

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

 @property (retain, nonatomic) NSString *city; 

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

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

但这里的问题是项目使用键“城市”作为未定义的关键在像一个常数的意义。 因此,假设我在我的应用程序中使用了“城市”键1000次,那么如果NSManagedObject的属性发生更改,例如cityName,则需要用新的键replace所有这些键。 在这种情况下,我需要使用谓词:

 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; 

所以如果属性被改变了,parsing器会告诉我这个项目有一个错误,我不能运行应用程序。 所以在我改变属性为常量后,我将能够运行应用程序

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

谢谢

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

 // .h extern const struct MBListAttributes { __unsafe_unretained NSString *title; } MBListAttributes; // .m const struct MBListAttributes MBListAttributes = { .title = @"title", }; 

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

我使用这个基于macros的解决scheme,以避免string文字,当我想要的密钥的名称。

它允许你以这种方式编写关键名字:

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

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

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