gpt4 book ai didi

ios - 后台线程方法无法解决卡住问题

转载 作者:行者123 更新时间:2023-12-01 17:51:06 24 4
gpt4 key购买 nike

我遇到了应用冻结的问题,因此我使用Instruments来发现问题,并发现问题与CoreData保存和提取有关。我尝试了后台coredata方法(父级,子级,通知),但我的问题尚未解决。我也提到了http://martiancraft.com/blog/2015/03/core-data-stack/,但不知道该方法在我的应用程序中是如何实现的。

仪器日志:
https://www.dropbox.com/s/agjtw1wqubsgwew/Instruments9.trace.zip?dl=0

保存到数据库

  -(void)updateThreadEntityWithSyncDetails:(NSMutableDictionary *)inDictionary
{

NSString *loginUser=[[NSUserDefaults standardUserDefaults] valueForKey:@"currentUser"];

AppDelegate *sharedDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [sharedDelegate managedObjectContext];

// NSManagedObjectContext *writerContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
// [writerContext setPersistentStoreCoordinator:[sharedDelegate persistentStoreCoordinator]];

// create main thread MOC
// context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
// context.parentContext = writerContext;

// NSManagedObjectContext *contextforThread = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];

// contextforThread.parentContext = context;

// [contextforThread performBlock:^{




NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ThreadInfo"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *userPredicate = [NSPredicate predicateWithFormat:@"userEmail == %@",loginUser];
NSPredicate *threadPredicate = [NSPredicate predicateWithFormat:@"threadID == %@",[inDictionary valueForKey:@"thread"]];
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates: @[userPredicate, threadPredicate]];
[fetchRequest setPredicate:compoundPredicate];

NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:nil];
for (ThreadInfo *threadInfo in fetchedObjects)
{
if([[inDictionary allKeys] containsObject:@"userEmail"])
{
if([inDictionary valueForKey:@"userEmail"]!=[NSNull null])
{
threadInfo.userEmail=[inDictionary valueForKey:@"userEmail"];
}
}
if([[inDictionary allKeys] containsObject:@"badgeValue"])
{
if([inDictionary valueForKey:@"badgeValue"]!=[NSNull null])
{
threadInfo.badgeValue=[inDictionary valueForKey:@"badgeValue"];
}
}


if([[inDictionary allKeys] containsObject:@"choice4Percentage"])
{
if([inDictionary valueForKey:@"choice4Percentage"]!=[NSNull null])
{
threadInfo.choice4Percentage=[inDictionary valueForKey:@"choice4Percentage"];
}
}
if([[inDictionary allKeys] containsObject:@"choice5Percentage"])
{
if([inDictionary valueForKey:@"choice5Percentage"]!=[NSNull null])
{
threadInfo.choice5Percentage=[inDictionary valueForKey:@"choice5Percentage"];
}
}

}

NSError *error;
if(![context save:&error]) {
NSLog(@"Child error : %@",error);

}

// [context performBlock:^{
// NSError *error;
// if(![context save:&error]) {
// NSLog(@"%@",error);
// }
// }];
// }];


}

FETCH
-(ThreadInfo *)retrieveSolicitationInfoForThreadID:(NSString*)inThreadID;
{
NSString *loginUser=[[NSUserDefaults standardUserDefaults] valueForKey:@"currentUser"];

AppDelegate *sharedDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [sharedDelegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ThreadInfo"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *userPredicate = [NSPredicate predicateWithFormat:@"userEmail == %@",loginUser];
NSPredicate *threadPredicate = [NSPredicate predicateWithFormat:@"threadID == %@",inThreadID];
\
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates: @[userPredicate, threadPredicate]];

[fetchRequest setPredicate:compoundPredicate];

NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:nil];
if(fetchedObjects.count!=0)
{
ThreadInfo *threadInfo=[fetchedObjects objectAtIndex:0];
return threadInfo;
}
return nil;
}

同步
-(void)updateSolicitationWithSyncDetails:(NSDictionary *)inDictionary
{
NSMutableDictionary *paramDict=[NSMutableDictionary dictionaryWithDictionary:inDictionary];
NSString *userEmail=[[NSUserDefaults standardUserDefaults] valueForKey:@"currentUser"];

[paramDict setObject:[NSNumber numberWithBool:NO] forKey:@"isSystemMessage"];
[paramDict setObject:userEmail forKey:@"userEmail"];

if([[inDictionary allKeys] containsObject:@"owned"])
{
BOOL isDuplicate=[[IXDataBaseManager sharedNetworkDataManager] checkForExistenceOfThreadDetailsForSolicitationID:[inDictionary objectForKey:@"solicitation"]];// FETCH
if(!isDuplicate)
{
int randomIndex=[[IXNetworkDataManager sharedNetworkDataManager] getIndexForColorImageForTab:@"OUT"];
[paramDict setObject:message forKey:@"threadDescription"];
[paramDict setObject:[NSNumber numberWithInt:randomIndex] forKey:@"colorCode"];

BOOL isDuplicateVal=[[IXDataBaseManager sharedNetworkDataManager] checkForExistenceOfSolicitationID:[inDictionary objectForKey:@"solicitation"]];// FETCH
[paramDict setObject:message forKey:@"threadDescription"];

ThreadInfo *threadInfo=[[IXDataBaseManager sharedNetworkDataManager] retrieveSolicitationInfoForThreadID:[inDictionary objectForKey:@"solicitation"]];
[paramDict setObject:threadInfo.threadID forKey:@"thread"];
[[IXDataBaseManager sharedNetworkDataManager] updateThreadEntityWithSyncDetails:paramDict];
}
}
}

最佳答案

首先,感谢您立即提供了代码片段和跟踪。那很有帮助。

因此,查看跟踪和代码。
-updateThreadEntityWithSyncDetails:在主线程上被调用,占该时间的33%。不好。

您正在通过nil传递error: 从来没有这样做。始终传递错误指针,并检查调用结果以查看是否存在错误。

这个条件可以使工作更加清洁:

if([[inDictionary allKeys] containsObject:@"userEmail"])
{
if([inDictionary valueForKey:@"userEmail"]!=[NSNull null])
{
threadInfo.userEmail=[inDictionary valueForKey:@"userEmail"];
}
}

考虑:
if (inDictionary[@"userEmail"] != nil && inDictionary[@"userEmail"] != [NSNull null]) {
threadInfo.userEmail = inDictionary[@"userEmail"];
}

更容易阅读。

这种方法的重新编写将使工作脱离主线程:
- (void)updateThreadEntityWithSyncDetails:(NSMutableDictionary*)inDictionary
{
NSString *loginUser = [[NSUserDefaults standardUserDefaults] valueForKey:@"currentUser"];

AppDelegate *sharedDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[context setParentContext:[sharedDelegate managedObjectContext]];

[context performBlock:^{
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"ThreadInfo"];
[fetchRequest setReturnsObjectsAsFaults:NO];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"userEmail == %@ && threadID == %@",loginUser, inDictionary[@"thread"]];

NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:nil];
for (ThreadInfo *threadInfo in fetchedObjects) {
if (inDictionary[@"userEmail"] != nil && inDictionary[@"userEmail"] != [NSNull null]) {
threadInfo.userEmail = inDictionary[@"userEmail"];
}
if (inDictionary[@"badgeValue"] != nil && inDictionary[@"badgeValue"] != [NSNull null]) {
threadInfo.badgeValue = inDictionary[@"badgeValue"];
}
if (inDictionary[@"choice4Percentage"] != nil && inDictionary[@"choice4Percentage"] != [NSNull null]) {
threadInfo.choice4Percentage = inDictionary[@"choice4Percentage"];
}
if (inDictionary[@"choice5Percentage"] != nil && inDictionary[@"choice5Percentage"] != [NSNull null]) {
threadInfo.choice5Percentage = inDictionary[@"choice5Percentage"];
}
}

NSError *error = nil;
if (![context save:&error]) {
NSLog(@"Child error : %@",error);

}
}];
}

仍可能会阻塞主线程,因为我猜测大部分CPU时间都在执行此访存中。提取速度很慢。您在该提取中有两个字符串比较。那是不好的,应该纠正。如果ThreadID不是字符串,则取反。否则,这只是糟糕的数据模型设计,除了修复该提取操作之外,不会有太多帮助。

您的另一个真正慢点是 -checkForExistenceOfThreadDetailsForThreadID:。您没有发布该方法,但我怀疑这是相同的问题,您的提取要花费大量的时间,并且它在主队列中。

总体而言,这的设计很差,需要重新设计。您正在比较数据存储中的字符串,这是检索数据的最慢方法之一。您也位于主线程上,可以处理不需要在主线程上出现的事情。

记住黄金法则,如果用户未操纵数据,则操纵绝不能在主队列上。没有异常(exception)。

关于ios - 后台线程方法无法解决卡住问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30364411/

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