gpt4 book ai didi

iphone - iOS 核心数据何时保存上下文?

转载 作者:IT王子 更新时间:2023-10-29 08:09:17 25 4
gpt4 key购买 nike

由于并发和多线程,我的核心数据随机崩溃。我知道核心数据不是线程安全的。我还找到了其他几个关于如何创建 ThreadedDataService 并为每个线程实例化单独上下文的答案。

目前这对我来说有点难以接受,所以我正在尝试寻找更简单的出路。

我目前尝试的解决方案很简单:通过主线程保存数据。但是,现在出现了一个新问题:死锁。该应用程序变得无响应,因为我每次插入新的 NSManagedObject 后都会调用保存。 (这是我最好的猜测)。

阅读 App Delegate 文档,我注意到它建议我将上下文保存在 applicationWillTerminate 中。

我的问题是:对于每分钟插入新事件的长时间运行的操作,并且用户不需要立即看到更新传播到所有 Controller ,什么时候是我保存上下文的好时机?我觉得为每条记录保存上下文可能有点矫枉过正?

-(void)insertNewEvent
{


// Create a new instance of the entity managed by the fetched results controller.
NSManagedObjectContext *context = [self.fetchedResultsController.managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsControllerfetchRequest] entity];
Event*newManagedObject = (Event*)[NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

//use accessor methods to set default values

// Save the context. > IS THIS REALLY NEEDED HERE?
NSError *error = nil;
if (![context save:&error])
{


}else
{
if(newManagedObject!=nil)
{
currentState= newManagedObject;
[currentRecord addEvent:newManagedObject];
//Is this call needed?
[self saveApplicationRecords];
}
}

}

我为我的所有托管对象定义了类似的方法,如果我每 10-15 分钟在主线程上调用这样的方法来保存未决更改,而不是在每次插入记录后都这样做就足够了吗?

-(void)saveApplicationRecords
{
NSLog(@"saveApplicationRecords");
NSManagedObjectContext *context = [self.applicationRecordsController.managedObjectContext];
// Save the context.
NSError *error = nil;
if (![context save:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

}

}

看完macbirdie的回复追问:这种方法在core data中合法吗?

-(Event*)insertAndReturnNewEventWithDate:(NSDate*)date_ type:(int)type
{
NSManagedObjectContext *context = [self.dreamEventsController managedObjectContext];
NSEntityDescription *entity = [[self.dreamEventsController fetchRequest] entity];
DreamEvent *newManagedObject = (Event*)[NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

//handle properties

NSError *error = nil;
if (![context save:&error])
{
return nil;

}else
{
return newManagedObject ;
}

}

谢谢!

最佳答案

您不必在过程的早期保存上下文,尤其是当您想要事后修改对象时。

在大多数情况下,您应该为即将对数据库执行的更改创建一个单独的 NSManagedObjectContext。因此,在其上创建对象,填写所需的属性,然后发送 save 并在主上下文中执行整个 mergeChangesFromContextDidSaveNotification: 技巧(很可能在主线程上运行,所以使用 performSelectorOnMainThread... 消息)。

默认情况下,由 NSManagedObjectContext 创建和返回的对象是自动释放的。例如,如果您创建了一个新对象并想在表单中对其进行编辑,您可以在创建对象之前调用 setRetainsRegisteredObjects: 并将 YES 设置为托管对象上下文,这样它就会保留对象创建,直到你完成它。请记住,不建议您自己管理 NSManagedObject 的生命周期 - 您应该让 NSManagedObjectContext 来完成它。因此,考虑到这一点,您不必保留 NSManagedObject。在保存操作之后,它被上下文注销并从内存中删除。您这边不需要任何东西。

更新问题部分的答案

如果您返回一个 NSManagedObjectID(使用 [object objectID])而不是对象本身,可能会更好。它允许通过上下文安全地处理对象,如果需要对象进行进一步编辑或数据检索(例如从其他上下文),他们可以单独从存储中获取它。

即使你不保存上下文,新创建的对象就在那里,然后你可以决定是否要保留该对象。

另一方面,在保存之后,如果上下文仍然存在,它可能会从内存缓存中将具有给定 NSManagedObjectID 的对象返回给您 - 而无需触及数据库。

另一方面 ;),在您的情况下,您可以非常安全地返回对象,因为创建它的 NSManagedObjectContext 仍然存在,所以该对象也将仍然存在,尽管已经在自动释放池。

关于iphone - iOS 核心数据何时保存上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8457847/

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