gpt4 book ai didi

cocoa - 使用 MagicalRecord 设计在后台保存的策略

转载 作者:行者123 更新时间:2023-12-03 17:56:05 24 4
gpt4 key购买 nike

最近我启动了一个新应用程序,只需要一个商店(没有基于文档的应用程序)。一段时间以来,我很高兴认为我终于可以摆脱 NSManagedObjectContext 的困扰......直到我想在后台保存:-(

现在我对自己的代码感到困惑。例如:

- (void)awakeFromInsert
{
[super awakeFromInsert];
[self resetCard];
self.creationDate = TODAY;
self.dictionary = [Dictionary activeDictionary];
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center postNotificationName:NOTE_NEWCARD object:self];
}

[Dictionary activeDictionary] 是一个 NSManagedObject 静态函数,返回指向在主线程中创建的 NSManagedObject 的指针。这将导致后台保存期间出现交叉/上下文错误。因为我的程序总是从同一个存储中读取,所以我想我可以避免写这个:

[Dictionary activeDictionaryWithContext:...]

我认为使用 MagicalRecord,只要我始终使用相同的后端,就可以避免传递上下文指针。我应该使用哪个函数来获取该上下文?

[NSManagedObjectContext MR_defaultContext]
[NSManagedObjectContext MR_context]
[NSManagedObjectContext MR_contextForCurrentThread]

在示例中,对象在通知中发送自身,这几乎会导致更多冲突。

  • 如果是通知,我应该始终只发送 objectID 吗?

在我看来,我的对象只有在主上下文中运行时才应该发出副作用操作/通知。然而,其中一些辅助操作会更改我的对象图,创建其他实体的新实例。

  • 如果我使用 [MagicalRecord MR_saveAll] 保存,我可以安全地忽略我提到的两个有问题的函数调用吗?

  • 我是否应该假设新后台保存上下文的对象将是主线程中对象的精确副本,而不调用这些额外的函数?

现在我遇到了问题,因为我从未期望 awakeFromInsert 会为同一存储的同一对象运行多次。我在想这样的事情:

- (void)awakeFromInsert
{
[super awakeFromInsert];
if ([self managedObjectContext] == [NSManagedObjectContext MR_defaultContext]) {
[self resetCard];
self.creationDate = TODAY;
self.dictionary = [Dictionary activeDictionary];
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center postNotificationName:NOTE_NEWCARD object:self];
}
}

这应该使我的 awakeFromInsert 代码仅运行一次,但不会在后台保存上下文中运行。我担心这样做会丢失信息

最佳答案

虽然您当然可以通过这种方式在通知中发送对象,但我建议反对这样做。请记住,即使在 CoreData 中使用新的父子上下文,NSManagedObjects 也不是线程安全的。如果您创建或导入对象,则需要先保存它们,然后再在其他上下文中使用它们。

MagicalRecord 提供了一个相对简单的 API 用于后台保存:

[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext){
MyEntity *newEntity = [MyEntity MR_createInContext:localContext];

//perform other entity operations here
}];

此 block 为您完成所有工作,而无需担心是否正确设置 NSManagedObjectContext。

您不应该在通知中传递 NSManagedObjects 的另一个原因是您不知道将在哪个线程上接收通知。这可能会导致崩溃,因为 NSManagedObjects 不是线程安全的。

您提供的通知方法的另一种替代方法是向 NSManagedObjectContextDidSaveNotification 添加观察者,并合并对该通知的更改。仅在保存对象后才会触发,并且可以安全地通过父子关系或持久存储(旧方式)跨上下文。

关于cocoa - 使用 MagicalRecord 设计在后台保存的策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13211753/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com