改变 NSArray 中的 ManagedObjects

发布于 2024-08-29 04:31:14 字数 1046 浏览 3 评论 0原文

我有一个名为“作业”的实体,具有两个名为“已完成”和“已记录”的布尔属性。 我正在尝试检索应用程序启动时尚未记录的所有已完成作业并将其更改为已记录。我可以使用此 fetchRequest 获取所有已完成但未记录的作业:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(completed == %@ && logged == %@)", [NSNumber numberWithBool:YES], [NSNumber numberWithBool:NO]];

然后,我将此谓词分配给 fetchRequest 并调用 [managementObjectContextexecuteFetchRequest:fetchRequest] 方法来获取满足此条件的所有作业实体的数组。这似乎工作正常并且返回正确数量的作业。

我一直在尝试做的是循环返回的 NSArray,将记录的属性设置为 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
      }
   }
}

感谢期待,

I have an entity called 'Job' with two boolean attributes named 'completed' and 'logged'.
I am trying to retrieve all completed jobs that have not been logged at app start-up and change them to logged. I'm able to get all the completed but unlogged jobs with this fetchRequest:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(completed == %@ && logged == %@)", [NSNumber numberWithBool:YES], [NSNumber numberWithBool:NO]];

I'm then assigning this predicate to a fetchRequest and calling the [managedObjectContext executeFetchRequest:fetchRequest] method to get an array of all Job entities that meet this criteria. This seems to work fine and is returning the correct number of jobs.

What I've been trying to do is loop through the NSArray returned, set the logged attribute to YES and then save. This seems to complete and doesn't return any errors but the changes are not persisted when the application quits. Where am I going wrong?

[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
      }
   }
}

Thanks in anticipation,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我还不会笑 2024-09-05 04:31:14

首先,您可以通过以下方式清理一些内容:

[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 并作为指针(您的声明不是)开始。如果不这样做,那么该指针的初始状态是未定义的,并且绝对不是零。
  • 检查以确保获取过程中没有错误。
  • 不需要对计数进行检查,因为快速枚举器会为您处理它。
  • 在每个对象之后保存是浪费的,除非您有数千个对象,否则在最后保存。
  • 在调试器中浏览代码并确保您正在获取对象并循环遍历它们。

First, you can clean things up a bit via:

[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]);
}
  • Note that I start with error being nil and being a pointer (your declaration was not). If you do not then the initial state of that pointer is undefined and definitely not nil.
  • Check to make sure there is no error in the fetch.
  • The check against count is unnecessary as the fast enumerator will handle it for you.
  • Saving after every object is wasteful, unless you have thousands of objects, save at the end.
  • Walk through your code in the debugger and make sure you are getting objects back and are looping over them.
我爱人 2024-09-05 04:31:14

一些可能有帮助的注释:

for 循环从 0 循环到比计数少 1。这将跳过最后一个作业。如果只有 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];
}

Some notes that may help:

The for loop is looping from 0 to one less than the count. This will skip the last job. If there is only 1 job, nothing will happen. Change the loop to:

for (int i = 0; i < [jobsToLog count]; i++)

or

for (int i = 0; i <= [jobsToLog count] - 1; i++)

When pulling objects out of NSArray the compiler will not know its type. You should explicitly cast the object:

  [(Job *)[jobsToLog objectAtIndex:i] setLogged:[NSNumber numberWithBool:YES]];

You can do both of the above using fast enumeration:

for(Job *thisJob in jobsToLog) {
  [thisJob setLogged:[NSNumber numberWithBool:YES];
}
高跟鞋的旋律 2024-09-05 04:31:14

如果您使用 KVC(键值编码)方法怎么办:

[[jobsToLog objectAtIndex:i] setValue:[NSNumber numberWithBool:YES] forKey:@"logged"];

您的自定义 NSManagedObject 类中有 setLogged 方法吗?

What if you use the KVC (Key Value Coding) method:

[[jobsToLog objectAtIndex:i] setValue:[NSNumber numberWithBool:YES] forKey:@"logged"];

Do you have a setLogged method in your custom NSManagedObject class?

九命猫 2024-09-05 04:31:14

我不是这里的专家,但我认为您需要通过使用 setPrimitiveValue: 告诉托管对象上下文来进行更改。所以试试这个。

[self willChangeValueForKey:@"logged"];
[self setPrimitiveValue:[NSNumber numberWithBool:YES] forKey:@"logged"];
[self didChangeValueForKey:@"logged"];

I'm no expert here but I think you need to tell the managed object context by using setPrimitiveValue: to make the changes. So try this.

[self willChangeValueForKey:@"logged"];
[self setPrimitiveValue:[NSNumber numberWithBool:YES] forKey:@"logged"];
[self didChangeValueForKey:@"logged"];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文