iPhone如何使用Core Data修改Persistent商店中包含的数据

时间:2010-02-27 19:45:44

标签: iphone objective-c core-data

我一直试图弄清楚如何修改持久性商店中包含的数据。 我正在使用UITabBarController编写一个包含多个视图的应用程序,我的核心数据方法主要位于主应用程序委托上,但我只会使用UItableViewController视图中的这些数据。

为了使用managedObjectContext中主应用程序委托中创建的UITableViewController,我在viewDidLoad:方法中使用以下内容:

MessageAppDelegate *appDelegate = (MessageAppDelegate *)[[UIApplication sharedApplication] delegate];
managedObjectContext = [appDelegate managedObjectContext];

然后,应用程序会在表格中显示一些消息,当用户选择UITableViewCelldidSelectRowAtIndexPath)时,我会获取消息对象的ID并调用以下方法:

[self readMessage:pk];
-(void)readMessage:(NSInteger)pk {  
// First I select the data
NSFetchRequest *request = [[NSFetchRequest alloc] init];
// had to setReturnsObjectsAsFaults to NO so I could access the message data
[request setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Message" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"pk == %d", pk];
[request setPredicate:predicate];

NSError *error;
NSArray *items = [self.managedObjectContext executeFetchRequest:request error:&error];
[request release];

// Then I update the object
for (Message *thisMessage in items) {
    //I display the message to the console before updating to check the value
    DLog(@"before reading message %@", thisMessage);
    // we set the message flat to YES
    [thisMessage setRead:YES];
    // we set some sample text here (just for testing)
    [thisMessage setMessageText:@"New message text"];
    // I then display the message to the console checking that the flag and text has been updated
    DLog(@"read message %@", thisMessage);
}

// Finally I save the updated message calling the function posted below
[self saveMOC];
}

- (void)saveMOC {
 NSError *error;
 if (![managedObjectContext save:&error]) {
  NSLog(@"there was an error saving the message!");
 }
}

之后数据会正确更新,如果我在保存后从managedObjectContext中获取数据,我会得到正确的值。 我通过在readMessage方法的末尾添加以下代码来验证这一点:

    request = [[NSFetchRequest alloc] init];
//required to avoid presenting objects as faults!!
[request setReturnsObjectsAsFaults:NO];
entity = [NSEntityDescription entityForName:@"Message" inManagedObjectContext:[self managedObjectContext]];
[request setEntity:entity];


//Set the sort descriptor
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"pk" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptors release];
[sortDescriptor release];

//Execute the request
NSMutableArray *mutableFetchResults = [[self.managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
    // Handle the error later
    DLog(@"ERROR: Unable to fetch the results");
}

[self setMessagesArray:mutableFetchResults];
    NSLog(@"Data now is: %@", mutableFetchResults);
[mutableFetchResults release];
[request release];

问题是,如果我从应用程序退出并再次启动它,我的所有消息都会丢失读取属性(或我做的任何其他更改),并且tableview会在首次保存到持久存储时加载数据。

2 个答案:

答案 0 :(得分:0)

尝试此操作,查看对象更改是否实际上已保存

- (void)saveMOC {
 NSError *error;
 if (![managedObjectContext save:&error]) {
  NSLog(@"there was an error saving the message!");
 } else {
  NSLog(@"The message was saved!");
 }
}

因此,对于每次成功的saveMOC调用,您都应该看到一条控制台消息。如果正在调用它并且您正在查看消息,那么您不能更改“读取消息”属性。您可以通过在使用断点或使用NSLog消息打印其值来设置之前和之后检查“读取消息”属性的值来检查这一点

答案 1 :(得分:0)

是-readMessage:在您的app delegate或视图控制器中定义的方法?我的猜测是,您正在更改不同托管对象上下文中对象的属性,而不是您尝试保存更改(应用程序委托中的MOC)的对象,实际上并不知道某些内容已更改。另一方面,保存更改的MOC永远不会保存(更改仅保留在内存中),并且在重新启动应用程序后,更改将丢失。

这可能是这种情况吗?