ios - 防止内存中的核心数据对象被不相关的代码删除?

标签 ios objective-c core-data

我正在开发一个非常糟糕的旧 Objective-C 应用程序。我正在处理的功能涉及从核心数据中获取不同的记录类型并将它们发送到服务器。并且必须先发送一种记录类型 (A),然后才能发送另一种记录类型 (B)。

编辑:A 指的是 ActivitySession 对象,B 指的是 ActivityRun 对象。

这就是问题所在:在应用程序的某处,有某种监听器在发送 A 记录后删除所有 B 记录。我花了一段时间试图找出发生这种情况的地方,但我没有运气。我的解决方案是在发送 A 记录之前将所有 B 记录加载到内存中(认为即使 B 记录从核心数据中删除,它们仍将存在于内存中)。但是我发现从核心数据中删除B记录后,我的记录数组也被清除了。

这是我正在谈论的逻辑的核心:

__block NSArray* activityRuns = [coreData fetchByEntitiyName:@"ActivityRun"];

NSLog(@"---> Sending %@ students", @([students count]));
return [self sendStudents:students withApiKey:apiKey]
.then(^{
  // This must happen before sending anything with activity references
  NSLog(@"---> Fetching activities");
  return [self fetchActivitiesWithApiKey:apiKey];
})
.then(^{
  NSArray* data = [coreData fetchByEntitiyName:@"ActivitySession"];
  NSLog(@"---> Sending %@ activity sessions", @([data count]));
  return [self sendActivitySessions:data withApiKey:apiKey].catch(failLogger(@"Failed to upload activity sessions", nil));
})
.then(^{
  NSLog(@"---> Sending %@ activity runs", @([activityRuns count]));
  return [self sendActivityRuns:activityRuns withApiKey:apiKey].catch(failLogger(@"Failed to upload activity runs", nil));
})

activityRuns 是我尝试发送的内存数据(使用 [self sendActivityRuns:activityRuns withApiKey:apiKey])。以下是 fetchByEntitiyName 的定义方式:

- (NSArray*) fetchByEntitiyName:(NSString*) entityName {
    NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] initWithEntityName:entityName];
    NSError* error = nil;
    NSArray* results = [_mainQueueContext executeFetchRequest:fetchRequest error:&error];
    if (results == nil) {
            ELog(@"--- Failed to fetch %@: %@", entityName, error);
            return @[];
    }
    return results;
}

activityRuns 没有在除了上面的代码片段之外的任何地方使用/传递,其中每个事件运行都是使用 HTTP 请求发送的。我尝试在创建数组之后(对象有效并包含数据)和发送之前(它们都是 nil)添加断点。

当某些内容删除记录时,如何防止核心数据在我的内存对象中乱码?

最佳答案

有几种方法可以做到这一点:

  • 最明显的是调用 NSManagedObjectContext.deleteObject,只需查找 deleteObject 并在那里放置断点。
  • 另一种是如果A和B有级联删除关系,你删除了parent,那么B也被删除了。例如,如果一个 Student 在如下属性中有一个 ActivityRun-s 列表:student.activityRuns(子对象数组),或反向属性 - activityRun.student(单个父对象),并且在您的 CoreData 模型中设置了此属性作为级联删除,如果你删除一个学生,所有的 activityRuns 都将消失。如果您使用“on delete set null”而不是“on delete cascade”,则子项不会被自动删除,但您必须在需要时手动删除它们。另一种方法是通过设置 activityRun.student = nil; 将子项与父项“分离”,它应该具有相同的效果(需要时再次必须手动删除)。
  • 另一种选择是,如果您对该数据库执行原始 SQL DELETE 查询

有一种方法可以查看幕后发生的所有 CoreData SQL 命令 - see here .

关于ios - 防止内存中的核心数据对象被不相关的代码删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50300708/

相关文章:

ios - 在 iOS 上查找文档目录的替代方法

iphone - 如何更改 UISearchbar 取消按钮的文本颜色

iphone - 执行获取请求 :error: A fetch request must have an entity

objective-c - viewDidLoad 中的 CoreData performFetch 不起作用

ios - 如何检测 iOS 应用程序是否正在越狱手机上运行?

ios - Truetime iOS Framework 出现超时错误

ios - 在应用程序中使用自定义框架的settings.bundle

ios - 为什么-tableView :heightForRowAtIndexPath: is a delegate method instead of a data source method?

带有类别的 iPhone 全局类,这是正确的吗?

iphone - 核心数据生成空 SQLite 数据库