【发布时间】:2013-04-29 18:41:19
【问题描述】:
我们知道 NSFetchRequest 的 propertiesToFetch 可以限制我们想要的属性,它可以减少内存的占用。 如果我们这样做:
request.propertiesToFetch = [NSArray arrayWithObjects:@"nID", nil];
和:
NSString *strID = [NSString stringWithFormat:@"%@", aPerson.nID];
cell.textLabel.text = strID;
然后调试输出(而不是触发错误):
CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK, t0.ZNID FROM ZPERSON t0 ORDER BY t0.ZNID
然而,当我向 NSManagedObject Person 的子类添加一个新的未建模属性时,发生了一件奇怪的事情。 就像这样:
@interface Person (Ex)
@property (nonatomic, retain) NSString *strTempName;
@end
@implementation Person (Ex)
@dynamic strTempName;
-(void)setStrTempName:(NSString *)strTempName
{
[self setPrimitiveValue:strTempName forKey:@"strTempName"];
}
-(NSString*)strTempName
{
return [self primitiveValueForKey:@"strTempName"];
}
这是访问新的未建模属性的地方:
NSString *strTT = aPerson.strTempName;
然后调试输出:
2013-05-06 10:43:07.789 TestCoreData[988:c07] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZBISFORTEST, t0.ZBISINTRASH, t0.ZNID, t0.ZSTRNAME, t0.ZSTROK, t0.ZSTROK2, t0.ZSTRTEST1, t0.ZSTRTEST2, t0.ZADEPART, t0.ZAMIDDLETHUMNAIL, t0.ZANORMALPIC, t0.ZASMALLTHUMNAIL FROM ZPERSON t0 WHERE t0.Z_PK = ?
2013-05-06 10:43:07.790 TestCoreData[988:c07] CoreData: annotation: sql connection fetch time: 0.0010s
2013-05-06 10:43:07.791 TestCoreData[988:c07] CoreData: annotation: total fetch execution time: 0.0018s for 1 rows.
2013-05-06 10:43:07.792 TestCoreData[988:c07] CoreData: annotation: fault fulfilled from database for : 0x898a030 <x-coredata://CAD35D43-F6B2-4463-B59B-C9A3CD488935/Person/p51846>
从上面的输出消息中,我们可以找到未建模的属性,而不是 SELECT t0.Z_ENT, t0.Z_PK, t0.ZNID,生成 SELECT all properties 语句并触发错误!
但是,我已经阅读了一些关于未建模属性的消息(here is link):
因为未建模的属性只是自定义的属性 NSManagedObject 子类而不是实体,错误对象知道 什么都没有。故障对象从数据模型初始化 这样他们响应的所有键都必须在数据模型中。这 意味着故障将无法可靠地响应未建模的请求 属性。
为什么会发生奇怪的事情?
提前致谢。
@匿名,
选择 1): 应用程序崩溃,调试输出显示:
2013-05-06 14:03:05.665 TestCoreData[1794:c07] -[Person strTempName]: unrecognized selector sent to instance 0x6ba77b0
2013-05-06 14:03:30.395 TestCoreData[1794:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Person strTempName]: unrecognized selector sent to instance 0x6ba77b0'
选择 2): 起初,willAccessValueForKey 等方法是发送 KVO 更改通知,就像 NSManagedObject.h 中的 cmets:
- (void)willAccessValueForKey:(NSString *)key; // read notification
- (void)didAccessValueForKey:(NSString *)key; // read notification (together with willAccessValueForKey used to maintain inverse relationships, to fire faults, etc.)
其次,在选择 2) 代码之后,奇怪的事情(触发故障)在我的应用程序中仍然存在。
也感谢您的回复。
【问题讨论】:
-
您正在开发 Mac OS X 应用程序或 iOS 应用程序?
-
@Shivan Raptor 它在 iOS 应用模拟器上。
-
为什么在定义getter和setter的时候都使用
@dynamic? -
因为在类别的实现中不允许使用@synthesize。
-
@jerrium 如果同时定义 getter 和 setter,则不需要
@dynamic。@dynamic告诉编译器:“你看不到 getter 和 setter,但它们被定义在你看不到它们的其他地方,不要用警告来打扰我”。如果您手动定义方法,则无需使用@dynamic。
标签: ios objective-c core-data