首先去CoreData。我这样做了吗?

时间:2014-01-03 19:06:30

标签: objective-c core-data

一点背景。我有一个历史上使用NSUserDefaults存储设置的应用程序。这导致了很多问题,因为我存储了关键的激活值,而NSUserDefaults似乎有时会消失,但这是另一个话题。我将过渡到使用CoreData,我想确保我正确地接近它。

我构建了一个名为Registry的实体,它具有key属性和每种可能数据类型的一个属性。这个想法是键值对,类似于使用NSUserDefaults存储键值对的方式。所以我的模型看起来像这样:

Model

我创建了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文档,我已经。我只是希望你们对我的作业进行评分:)

如果正确的话,我接下来的步骤就是围绕这一切编写一个包装器,以便更方便。

谢谢!

3 个答案:

答案 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上下文,则只需要插入它。

除此之外,对我来说似乎还可以。