gpt4 book ai didi

ios - 核心数据和线程

转载 作者:行者123 更新时间:2023-11-29 04:27:33 26 4
gpt4 key购买 nike

我使用以下代码从 Web 服务加载数据并将其存储在核心数据数据库中。

    dispatch_queue_t fetchQ = dispatch_queue_create("fetcher", NULL);
dispatch_async(fetchQ, ^{
NSArray *list = [WebService loadData];
dispatch_sync(dispatch_get_main_queue(), ^{
if (list != nil) {
for (NSDictionary *data in list) {

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:appDelegate.coreDataDatabase.managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id = %i", [[data objectForKey:@"id"] integerValue]];
[request setPredicate:predicate];

NSError *error = nil;
NSArray *data = [appDelegate.coreDataDatabase.managedObjectContext executeFetchRequest:request error:&error];

Object *object = [data objectAtIndex: 0];
if (object == nil) {
object = [NSEntityDescription insertNewObjectForEntityForName:@"Object" inManagedObjectContext:appDelegate.coreDataDatabase.managedObjectContext];
object.id = [NSNumber numberWithInteger:[[data objectForKey:@"id"] integerValue]];
}

object.name = [data objectForKey:@"name"];
}

[appDelegate.coreDataDatabase saveToURL:appDelegate.coreDataDatabase.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:nil];
}
});
});
dispatch_release(fetchQ);

代码已简化,但它应该代表序列。对 Web 服务的访问在后台运行。之后,在主线程中调用该商店。实际上应该没问题吧?

不幸的是,并非所有设备都适用。在我的所有设备和大多数其他设备上,都没有问题。在一些方面,但显然是这样,因为不幸的是,商店里有一些负面的 Bewertugnen 和几个问题。问题是他发现数据库中已经存在记录,并且没有不断地进行新的投资

感谢您的帮助,斯特凡

最佳答案

我很难理解你的实际问题。我不太清楚你的意思...

On some but apparently so, because unfortunately there are some negative Bewertugnen in the store and a couple of questions. The problem is that he finds an already existing record in the DB and not constantly new investing

所以我会做出我最好的猜测。

从代码中,我假设您正在使用 UIManagedDocument。

您不应直接保存UIManagedDocument (saveToUrl)。相反,您应该让它处理自动保存,因为它会适本地执行此操作。

如果您在 UIManagedDocument 上激活了 NSUndoManager,则无需执行任何操作。所有操作都会自动保存。如果你没有撤销管理器,你需要戳它让它知道它有脏数据。你可以这样做:

[managedDocument updateChangeCount:UIDocumentChangeDone];

但是,请注意 UIManagedDocument 使用嵌套上下文,并且存在一些与插入新对象相关的错误。也就是说,持久 ID 没有正确推回子上下文。我对您的问题的假设是您因此而获得重复的数据条目。

这个问题在一定程度上解决了这个问题。

Core Data could not fullfil fault for object after obtainPermanantIDs

基本上,考虑到您想继续使用 UIManagedDocument,您有多种选择。首先,获取永久ID。替换这一行:

[appDelegate.coreDataDatabase saveToURL:appDelegate.coreDataDatabase.fileURL forSaveOperation:UIDocumentSaveForOverwriting completionHandler:nil];

用这个(当然——处理错误——这只是传递0):

NSManagedObjectContext *moc = appDelegate.coreDataDatabase.managedObjectContext;
[moc obtainPermanentIDsForObjects:moc.insertedObjects.allObjects error:0];
[appDelegate.coreDataDatabase updateChangeCount:UIDocumentChangeDone];

这方面仍然存在一些问题,但非常罕见。您的代码似乎没有非常复杂的对象图,因此这应该足够了。

另一种选择是导入到单独的 MOC(UIManagedDocument 父上下文的子级)中,并在导入完成后重新获取主上下文。

使用您的代码示例,执行此操作的简单方法如下...

dispatch_queue_t fetchQ = dispatch_queue_create("fetcher", NULL);
dispatch_async(fetchQ, ^{
NSArray *list = [WebService loadData];
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
moc.parentContext = appDelegate.coreDataDatabase.managedObjectContext.parentContext;
for (NSDictionary *data in list) {
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id = %i", [[data objectForKey:@"id"] integerValue]];
[request setPredicate:predicate];

NSError *error = nil;
NSArray *data = [moc executeFetchRequest:request error:&error];
Object *object = [data objectAtIndex: 0];
if (object == nil) {
object = [NSEntityDescription insertNewObjectForEntityForName:@"Object" inManagedObjectContext:moc];
object.id = [NSNumber numberWithInteger:[[data objectForKey:@"id"] integerValue]];
}

object.name = [data objectForKey:@"name"];
}

// Save the MOC you just loaded everything into
[moc save:&error]; // handle error...
// Save the parent MOC, which is also the parent of your main MOC
moc = moc.parentContext;
[moc performBlock:^{
[moc save:&error]; // handle error
// When all the saves are done, run on the main queue and just refetch
// all the entities that were inserted.
dispatch_async(dispatch_get_main_queue(), ^{
// Here, use appDelegate.coreDataDatabase.managedObjectContext
// to refetch the objects that were altered. If you are using a
// table view or FRC just issue a refetch of the data and the
// main MOC will get everything that was modified.
});
}];
});
dispatch_release(fetchQ);

关于ios - 核心数据和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12120901/

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