一点背景。我有一个历史上使用NSUserDefaults存储设置的应用程序。这导致了很多问题,因为我存储了关键的激活值,而NSUserDefaults似乎有时会消失,但这是另一个话题。我将过渡到使用CoreData,我想确保我正确地接近它。
我构建了一个名为Registry的实体,它具有key属性和每种可能数据类型的一个属性。这个想法是键值对,类似于使用NSUserDefaults存储键值对的方式。所以我的模型看起来像这样:
我创建了NSManagedObjectModel的子类。据我所知,没有必要这样做,它带给你的唯一好处是代码更清晰。这是对的吗?
所以我写了一小段测试代码,看看我是否真的得到了它的工作原理。我没有做任何错误处理,我显然会在现实代码中做,这只是为了获得一般性的理解。 [编辑:有关正确错误处理的所有评论,我想我会更新,所以错误得到妥善处理。希望这也有助于其他观众学习]
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = appDelegate.managedObjectContext;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Registry"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"key == %@", @"Test"];
fetchRequest.predicate = predicate;
NSError *coreDataError;
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&coreDataError];
if (coreDataError != nil) {
NSLog(@"Error in executeFetchRequest: %@\r\n%@", coreDataError, coreDataError.userInfo);
}
Registry *testSetting1;
if ([fetchedObjects count] == 1) {
testSetting1 = [fetchedObjects objectAtIndex:0];
NSLog(@"Value of Test = %@", testSetting1.stringVal);
}
else{
testSetting1 = [NSEntityDescription
insertNewObjectForEntityForName:@"Registry"
inManagedObjectContext:self.managedObjectContext];
testSetting1.key = @"Test";
testSetting1.stringVal = @"ABC123";
[self.managedObjectContext save:&coreDataError];
if (coreDataError != nil) {
NSLog(@"Error in managedObjectContext save: %@\r\n%@", coreDataError, coreDataError.userInfo);
}
}
这似乎有效,我的设置像他们应该的那样坚持。我只是想确保我完全理解它是如何工作的。请不要回复说阅读Apple文档,我已经。我只是希望你们对我的作业进行评分:)
如果正确的话,我接下来的步骤就是围绕这一切编写一个包装器,以便更方便。
谢谢!
答案 0 :(得分:7)
你没有抓住并处理错误。对于开发人员来说,这是非常不良行为。每次看到传递错误指针的位置时,都应传递错误,然后检查错误情况是否发生。
即使您只是将错误打印到NSLog()
,必须检查错误,否则您会感到痛苦。
当您致电-executeFetchRequest:error:
时捕获错误。如果返回值为nil
,则表示存在错误。打印出错误。
当您致电-save:
时捕获错误。如果调用返回NO
,则表示存在错误。打印出错误。
如果我是一名教师,我会严厉标记,因为这是一个等待咬你的隐藏问题。
答案 1 :(得分:3)
您使用的NSError
成语不正确。检查返回结果,如果结果为零,请查看NSError
。
NSError *coreDataError;
NSArray *fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&coreDataError];
if (!fetchedObjects) {
NSLog(@"Error in executeFetchRequest: %@\r\n%@", coreDataError, coreDataError.userInfo);
}
和
BOOL saveOK = [self.managedObjectContext save:&coreDataError];
if (!saveOK) {
NSLog(@"Error in managedObjectContext save: %@\r\n%@", coreDataError, coreDataError.userInfo);
}
我也对这句话持怀疑态度:
if ([fetchedObjects count] == 1) {
您是否有机会获得密钥的重复条目?如果是这样,那么一旦你有一个重复,你将有很多(因为那时永远fetchedObjects.count > 1
)。 <怎么样
if ([fetchedObjects count] >= 1) {
代替?
答案 2 :(得分:2)
行[self.managedObjectContext insertObject:testSetting1];
不是必需的,Registry
会在创建时插入到该上下文中。
如果您在创建时传递nil
上下文,则只需要插入它。
除此之外,对我来说似乎还可以。