核心数据。 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子类中对其进行更改。