我有一个名为'Job'的实体,有两个名为'completed'和'logged'的布尔属性。 我正在尝试检索所有尚未在应用启动时记录的已完成作业,并将其更改为已记录。我可以使用此fetchRequest获取所有已完成但未记录的作业:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(completed == %@ && logged == %@)", [NSNumber numberWithBool:YES], [NSNumber numberWithBool:NO]];
然后我将此谓词分配给fetchRequest并调用[managedObjectContext executeFetchRequest:fetchRequest]方法以获取满足此条件的所有Job实体的数组。这似乎工作正常,并返回正确数量的工作。
我一直在尝试做的是循环返回NSArray,将logged属性设置为YES然后保存。这似乎已完成,并且不会返回任何错误,但在应用程序退出时不会保留更改。我哪里错了?
[fetchRequest setPredicate:predicate];
NSError error;
NSArray jobsToLog = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
if ([jobsToLog count] > 0) {
for (int i = 0; i < [jobsToLog count] - 1; i++) {
[[jobsToLog objectAtIndex:i] setLogged:[NSNumber numberWithBool:YES]];
// Commit the changes made to disk
error = nil;
if (![managedObjectContext save:&error]) {
// An error occurred
}
}
}
感谢您的期待,
答案 0 :(得分:1)
可能会有所帮助的一些注意事项:
for循环从0循环到小于计数的1。这将跳过上一份工作。如果只有一份工作,那么什么都不会发生。将循环更改为:
for (int i = 0; i < [jobsToLog count]; i++)
或
for (int i = 0; i <= [jobsToLog count] - 1; i++)
当从NSArray中提取对象时,编译器将不知道其类型。您应该显式地转换对象:
[(Job *)[jobsToLog objectAtIndex:i] setLogged:[NSNumber numberWithBool:YES]];
您可以使用快速枚举执行以上两种操作:
for(Job *thisJob in jobsToLog) {
[thisJob setLogged:[NSNumber numberWithBool:YES];
}
答案 1 :(得分:1)
首先,你可以通过以下方式清理一下:
[fetchRequest setPredicate:predicate];
NSError *error = nil;
NSArray jobsToLog = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
NSAssert1(error == nil, @"Error retrieving jobs: %@", [error userInfo]);
for (id job in jobsToLog) {
[job setValue:[NSNumber numberWithBool:YES] forKey:@"logged"];
}
if (![managedObjectContext save:&error]) {
NSAssert1(NO, @"Failed to save %@", [error userInfo]);
}
error
开始是nil并且是一个指针(你的声明不是)。如果不这样做,那么该指针的初始状态是未定义的,绝对不是nil。答案 2 :(得分:0)
如果您使用KVC(键值编码)方法怎么办:
[[jobsToLog objectAtIndex:i] setValue:[NSNumber numberWithBool:YES] forKey:@"logged"];
您的自定义NSManagedObject类中是否有setLogged方法?
答案 3 :(得分:0)
我不是这里的专家,但我认为您需要使用setPrimitiveValue来告知托管对象上下文:进行更改。试试吧。
[self willChangeValueForKey:@"logged"];
[self setPrimitiveValue:[NSNumber numberWithBool:YES] forKey:@"logged"];
[self didChangeValueForKey:@"logged"];