gpt4 book ai didi

ios - Core-Data executeFetchRequest 在后台线程卡住App

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:00:53 26 4
gpt4 key购买 nike

我有一个 saveMOC,它是 mainMOC 的直接父级,我需要在线获取另一个 tmpMOC 以免阻塞我的 UI,同时从互联网上获取大量记录。

我的应用卡住了。我可以将其缩小到这一点:

       fetchedItems = [tmpMOC executeFetchRequest:fetchRequest error:&error];

我试图将其包含在 dispatch_sync[moc.parentcontext.parentcontext.persistentStoreCoordinator lock/unlock][whatevermoc performBlockAndWait] 中。 ..

我也尝试获取_mainMOC……没办法……

我知道 executeFetchRequest 不是线程安全的,那么,我如何锁定我需要锁定的任何内容以确保我没有插入 double ?

有人可以帮忙吗?

更新 (1)_saveMOC AppDelegate 中的实例化:

- (NSManagedObjectContext *)managedObjectContext
{
if (_mainMOC != nil) {
return _mainMOC;
}

if (_saveMOC == nil) {
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_saveMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_saveMOC setPersistentStoreCoordinator:coordinator];
[_saveMOC setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
}
}
if (_mainMOC == nil) {
_mainMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_mainMOC setParentContext:_saveMOC];
[_mainMOC setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveContextChanges:) name:NSManagedObjectContextDidSaveNotification object:_mainMOC];

temporaryMOC在 MainViewController 中创建:

    NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
temporaryContext.parentContext = _mainMOC;

[temporaryContext performBlock:^{ //AndWait
NSError *error=nil;
Feed *feed=(Feed *)[temporaryContext existingObjectWithID:feedID error:&error];

//...
[RSSParser parseRSSFeedForRequest:req success:^(NSArray *feedItems)
{
NSLog(@"[MasterViewController::fetchPosts] inserting %d Posts.../OK", (int)[feedItems count]);
feed.valid = [NSNumber numberWithBool:YES];
for(RSSItem *i in feedItems)
{
[self createPostInFeed:feed withTitle:i.title withContent:(i.content?i.content:i.itemDescription) withURL:[i.link absoluteString] withDate:(i.pubDate?i.pubDate:[NSDate date]) inMOC:temporaryContext];
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"NewPostsFetched" object:f];

然后卡住发生在 createPostInFeed 中:

 // @synchronized(fetchRequest) { // THIS DOESN'T CHANGE ANYTHING
// [moc.persistentStoreCoordinator lock]; // THIS NEITHER
NSArray *fetchedItems;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *ent = [NSEntityDescription entityForName:@"Post" inManagedObjectContext:moc];
fetchRequest.entity = ent;

fetchRequest.propertiesToFetch = [NSArray arrayWithObjects:@"title", @"url", @"feed.name", nil];
[fetchRequest setResultType:NSDictionaryResultType];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"title == %@ AND url == %@ AND feed.rss == %@", title, url, feed.rss];
NSError *error = nil;
fetchedItems = [moc executeFetchRequest:fetchRequest error:&error]; // FREEZES HERE
// [moc.persistentStoreCoordinator unlock]; // THIS DOESN'T CHANGE ANYTHING
// } // Synchronized neither...

更新 (2):这是 Time Profiler 看到的内容。 enter image description here

更新 (3): block 编辑:

NSUInteger fetchedItems;
NSString *feedRSS=feed.rss;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *ent = [NSEntityDescription entityForName:@"Post" inManagedObjectContext:moc];
fetchRequest.entity = ent;

fetchRequest.predicate = [NSPredicate predicateWithFormat:@"title == %@ AND url == %@ AND feed.rss == %@", title, url, feedRSS];
NSLog(@"MainViewController::createPostInFeed> Before fetchRequest for %@ (%@)", title, url);
NSError *error = nil;
fetchedItems = [moc countForFetchRequest:fetchRequest error:&error];
NSLog(@"MainViewController::createPostInFeed> After fetchRequest for %@ (%@)", title, url); // THIS NSLOGGING NEVER HAPPENS

更新 (4):调用树倒置的新探查器图片。 enter image description here

最佳答案

createPostInFeed 的目标是什么?你表明你正在做一个获取,但是你用这个获取做什么?这是“插入或更新”检查吗?或者它只是一个“插入或跳过”测试?

任何提取都会锁定 NSPersistentStoreCoordinator 并导致您的应用程序在执行提取时可能锁定。有一些方法可以缓解这种情况:

  1. 运行仪器
  2. 提高抓取效率
  3. 如果您不需要对象(在插入或跳过测试中),则改为计数
  4. 获取后台队列并确保您的主 MOC 具有避免锁定所需的所有对象

您的仪器资料向您展示了什么?

createPostInFeed 对获取的结果做了什么?

关于ios - Core-Data executeFetchRequest 在后台线程卡住App,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23504936/

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