保存到核心数据应用程序被冻结几秒钟

我有一些logging在服务器,当背景前台应用程序服务器将发送所有logging,从客户端我节省所有数据到coredata。 保存时我需要检查这些数据是否已经存在,有时我需要在保存之前从数据库中获取一些数据,但在这段时间,我的应用程序被冻结了,只有在所有的更新和储蓄完成后,它才能正常工作。

分析器: https : //www.dropbox.com/s/epw1939vxakxt7k/Instruments5.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:@"thread"]) { if([inDictionary valueForKey:@"thread"]!=[NSNull null]) { threadInfo.threadID=[inDictionary valueForKey:@"thread"]; } } if([[inDictionary allKeys] containsObject:@"key"]) { if([inDictionary valueForKey:@"key"]!=[NSNull null]) { threadInfo.threadKey=[inDictionary valueForKey:@"key"]; } } if([[inDictionary allKeys] containsObject:@"secret_seed"]) { if([inDictionary valueForKey:@"secret_seed"]!=[NSNull null]) { threadInfo.threadSecret=[NSString stringWithFormat:@"%@",[inDictionary valueForKey:@"secret_seed"]]; } } if([[inDictionary allKeys] containsObject:@"r_key"]) { if([inDictionary valueForKey:@"r_key"]!=[NSNull null]) { threadInfo.remoteKey=[inDictionary valueForKey:@"r_key"]; } } if([[inDictionary allKeys] containsObject:@"solicitation"]) { if([inDictionary valueForKey:@"solicitation"]!=[NSNull null]) { threadInfo.solicitationID=[inDictionary valueForKey:@"solicitation"]; } } if([[inDictionary allKeys] containsObject:@"r_secret"]) { if([inDictionary valueForKey:@"r_secret"]!=[NSNull null]) { threadInfo.remoteSecret=[inDictionary valueForKey:@"r_secret"]; } } if([[inDictionary allKeys] containsObject:@"icon_idx"]) { if([inDictionary valueForKey:@"icon_idx"]!=[NSNull null]) { threadInfo.avatarIconIndex=[inDictionary valueForKey:@"icon_idx"]; } } if([[inDictionary allKeys] containsObject:@"icon_color_idx"]) { if([inDictionary valueForKey:@"icon_color_idx"]!=[NSNull null]) { threadInfo.avatarColorIndex=[inDictionary valueForKey:@"icon_color_idx"]; } } if([[inDictionary allKeys] containsObject:@"encrypted_r_secret"]) { if([inDictionary valueForKey:@"encrypted_r_secret"]!=[NSNull null]) { threadInfo.encryptedRemoteSecret=[inDictionary valueForKey:@"encrypted_r_secret"]; } } if([[inDictionary allKeys] containsObject:@"isSystemMessage"]) { if([inDictionary valueForKey:@"isSystemMessage"]!=[NSNull null]) { threadInfo.isSystemMessage=[inDictionary valueForKey:@"isSystemMessage"]; } } if([[inDictionary allKeys] containsObject:@"ref"]) { if([inDictionary valueForKey:@"ref"]!=[NSNull null]) { threadInfo.systemReferenceURL=[inDictionary valueForKey:@"ref"]; } } if([[inDictionary allKeys] containsObject:@"url"]) { if([inDictionary valueForKey:@"url"]!=[NSNull null]) { threadInfo.systemMessageURL=[inDictionary valueForKey:@"url"]; } } if([[inDictionary allKeys] containsObject:@"thumbnailImageURL"]) { if([inDictionary valueForKey:@"thumbnailImageURL"]!=[NSNull null]) { threadInfo.thumbnailImageURL=[inDictionary valueForKey:@"thumbnailImageURL"]; } } if([[inDictionary allKeys] containsObject:@"from"]) { if([inDictionary valueForKey:@"from"]!=[NSNull null]) { threadInfo.receiverEmail=[inDictionary valueForKey:@"from"]; } } if([[inDictionary allKeys] containsObject:@"isQuiz"]) { if([inDictionary valueForKey:@"isQuiz"]!=[NSNull null]) { threadInfo.isQuiz=[inDictionary valueForKey:@"isQuiz"]; } } if([[inDictionary allKeys] containsObject:@"replied"]) { if([inDictionary valueForKey:@"replied"]!=[NSNull null]) { threadInfo.replied=[inDictionary valueForKey:@"replied"]; } } if([[inDictionary allKeys] containsObject:@"owned"]) { if([inDictionary valueForKey:@"owned"]!=[NSNull null]) { BOOL isOwner=[[inDictionary valueForKey:@"owned"] boolValue]; if([[inDictionary allKeys] containsObject:@"solicitation"]) { if([inDictionary valueForKey:@"solicitation"]!=[NSNull null]) { if(isOwner) { if ([[inDictionary valueForKey:@"solicitation"] isEqualToString:[inDictionary valueForKey:@"thread"]]) { threadInfo.isRequester=[NSNumber numberWithBool:YES]; } else { threadInfo.isSender=[NSNumber numberWithBool:YES]; } } else { // threadInfo.isProvider=[NSNumber numberWithBool:YES]; if ([[inDictionary valueForKey:@"solicitation"] isEqualToString:[inDictionary valueForKey:@"thread"]]) { threadInfo.isProvider=[NSNumber numberWithBool:YES]; } else { threadInfo.isReceiver=[NSNumber numberWithBool:YES]; } } } else { if(isOwner) { threadInfo.isSender=[NSNumber numberWithBool:YES]; } else { threadInfo.isReceiver=[NSNumber numberWithBool:YES]; } } } else { if(isOwner) { threadInfo.isSender=[NSNumber numberWithBool:YES]; } else { threadInfo.isReceiver=[NSNumber numberWithBool:YES]; } } } } if([[inDictionary allKeys] containsObject:@"options"]) { if([inDictionary valueForKey:@"options"]!=[NSNull null]) { NSMutableArray *accArray=[inDictionary valueForKey:@"options"]; NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:accArray]; threadInfo.pollOptions = arrayData; } } if([[inDictionary allKeys] containsObject:@"isAnyReceiverActivity"]) { if([inDictionary valueForKey:@"isAnyReceiverActivity"]!=[NSNull null]) { threadInfo.isAnyReceiverActivity=[inDictionary valueForKey:@"isAnyReceiverActivity"]; } } if([[inDictionary allKeys] containsObject:@"pollAnswerList"]) { if([inDictionary valueForKey:@"pollAnswerList"]!=[NSNull null]) { NSMutableDictionary *accDict=[inDictionary valueForKey:@"pollAnswerList"]; NSData *dictData = [NSKeyedArchiver archivedDataWithRootObject:accDict]; threadInfo.pollAnswerList = dictData; } } if([[inDictionary allKeys] containsObject:@"responseCount"]) { if([inDictionary valueForKey:@"responseCount"]!=[NSNull null]) { threadInfo.responseCount=[inDictionary valueForKey:@"responseCount"]; } } if([[inDictionary allKeys] containsObject:@"isSender"]) { if([inDictionary valueForKey:@"isSender"]!=[NSNull null]) { threadInfo.isSender=[NSNumber numberWithBool:[[inDictionary valueForKey:@"isSender"] boolValue]]; } } if([[inDictionary allKeys] containsObject:@"isRequester"]) { if([inDictionary valueForKey:@"isRequester"]!=[NSNull null]) { threadInfo.isRequester=[NSNumber numberWithBool:[[inDictionary valueForKey:@"isRequester"] boolValue]]; } } if([[inDictionary allKeys] containsObject:@"image"]) { if([inDictionary valueForKey:@"image"]!=[NSNull null]) { threadInfo.image=[inDictionary valueForKey:@"image"]; } } if([[inDictionary allKeys] containsObject:@"isReceiver"]) { if([inDictionary valueForKey:@"isReceiver"]!=[NSNull null]) { threadInfo.isReceiver=[NSNumber numberWithBool:[[inDictionary valueForKey:@"isReceiver"] boolValue]]; } } if([[inDictionary allKeys] containsObject:@"colorCode"]) { if([inDictionary valueForKey:@"colorCode"]!=[NSNull null]) { threadInfo.colorCode=[inDictionary valueForKey:@"colorCode"]; } } if([[inDictionary allKeys] containsObject:@"solicitationCount"]) { if([inDictionary valueForKey:@"solicitationCount"]!=[NSNull null]) { threadInfo.solicitationCount=[inDictionary valueForKey:@"solicitationCount"]; } } if([[inDictionary allKeys] containsObject:@"solicitationNumber"]) { if([inDictionary valueForKey:@"solicitationNumber"]!=[NSNull null]) { threadInfo.solicitationNumber=[inDictionary valueForKey:@"solicitationNumber"]; } } if([[inDictionary allKeys] containsObject:@"disliked"]) { if([inDictionary valueForKey:@"disliked"]!=[NSNull null]) { threadInfo.hasDislikes=[NSNumber numberWithBool:[[inDictionary valueForKey:@"disliked"] boolValue]]; } } if([[inDictionary allKeys] containsObject:@"liked"]) { if([inDictionary valueForKey:@"liked"]!=[NSNull null]) { threadInfo.hasLikes=[NSNumber numberWithBool:[[inDictionary valueForKey:@"liked"] boolValue]]; } } if([[inDictionary allKeys] containsObject:@"removed"]) { if([inDictionary valueForKey:@"removed"]!=[NSNull null]) { threadInfo.isThreadRemoved=[NSNumber numberWithBool:[[inDictionary valueForKey:@"removed"] boolValue]]; } } if([[inDictionary allKeys] containsObject:@"closed"]) { if([inDictionary valueForKey:@"closed"]!=[NSNull null]) { threadInfo.isThreadEnded=[NSNumber numberWithBool:[[inDictionary valueForKey:@"closed"] boolValue]]; } } if([[inDictionary allKeys] containsObject:@"blocked"]) { if([inDictionary valueForKey:@"blocked"]!=[NSNull null]) { threadInfo.isThreadBlocked=[NSNumber numberWithBool:[[inDictionary valueForKey:@"blocked"] boolValue]]; } } if([[inDictionary allKeys] containsObject:@"hasComments"]) { if([inDictionary valueForKey:@"hasComments"]!=[NSNull null]) { threadInfo.hasComments=[NSNumber numberWithBool:[[inDictionary valueForKey:@"hasComments"] boolValue]]; } } if([[inDictionary allKeys] containsObject:@"isProvider"]) { if([inDictionary valueForKey:@"isProvider"]!=[NSNull null]) { threadInfo.isProvider=[NSNumber numberWithBool:[[inDictionary valueForKey:@"isProvider"] boolValue]]; } } if([[inDictionary allKeys] containsObject:@"messageDescription"]) { if([inDictionary valueForKey:@"messageDescription"]!=[NSNull null]) { threadInfo.messageDescription=[inDictionary valueForKey:@"messageDescription"]; } } if([[inDictionary allKeys] containsObject:@"commentCount"]) { if([inDictionary valueForKey:@"commentCount"]!=[NSNull null]) { threadInfo.commentCount=[NSNumber numberWithInteger:[[inDictionary valueForKey:@"commentCount"] integerValue]]; } } if([[inDictionary allKeys] containsObject:@"threadDate"]) { if([inDictionary valueForKey:@"threadDate"]!=[NSNull null]) { threadInfo.threadDate=[inDictionary valueForKey:@"threadDate"]; } } if([[inDictionary allKeys] containsObject:@"receivedDate"]) { if([inDictionary valueForKey:@"receivedDate"]!=[NSNull null]) { threadInfo.receivedDate=[inDictionary valueForKey:@"receivedDate"]; } } if([[inDictionary allKeys] containsObject:@"closedDate"]) { if([inDictionary valueForKey:@"closedDate"]!=[NSNull null]) { threadInfo.closedDate=[inDictionary valueForKey:@"closedDate"]; } } if([[inDictionary allKeys] containsObject:@"blockedDate"]) { if([inDictionary valueForKey:@"blockedDate"]!=[NSNull null]) { threadInfo.blockedDate=[inDictionary valueForKey:@"blockedDate"]; } } if([[inDictionary allKeys] containsObject:@"threadDescription"]) { if([inDictionary valueForKey:@"threadDescription"]!=[NSNull null]) { threadInfo.threadMessage=[inDictionary valueForKey:@"threadDescription"]; } } if([[inDictionary allKeys] containsObject:@"receiverEmail"]) { if([inDictionary valueForKey:@"receiverEmail"]!=[NSNull null]) { threadInfo.receiverEmail=[inDictionary valueForKey:@"receiverEmail"]; } } if([[inDictionary allKeys] containsObject:@"to"]) { if([inDictionary valueForKey:@"to"]!=[NSNull null]) { id toValue=[inDictionary valueForKey:@"to"]; if([toValue isKindOfClass:[NSString class]]) { if ([toValue rangeOfString:@"@"].location != NSNotFound) { threadInfo.receiverEmail=[NSString stringWithFormat:@"%@",toValue]; } } else { NSMutableArray *accArray=[NSMutableArray arrayWithArray:toValue]; NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:accArray]; threadInfo.solicitationList = arrayData; } } } //Poll if([[inDictionary allKeys] containsObject:@"isPoll"]) { if([inDictionary valueForKey:@"isPoll"]!=[NSNull null]) { threadInfo.isPoll=[inDictionary valueForKey:@"isPoll"]; } } if([[inDictionary allKeys] containsObject:@"type"]) { if([inDictionary valueForKey:@"type"]!=[NSNull null]) { threadInfo.pollType=[inDictionary valueForKey:@"type"]; } } if([[inDictionary allKeys] containsObject:@"scope"]) { if([inDictionary valueForKey:@"scope"]!=[NSNull null]) { threadInfo.pollScope=[inDictionary valueForKey:@"scope"]; } } if([[inDictionary allKeys] containsObject:@"isPollSender"]) { if([inDictionary valueForKey:@"isPollSender"]!=[NSNull null]) { threadInfo.isPollSender=[inDictionary valueForKey:@"isPollSender"]; } } if([[inDictionary allKeys] containsObject:@"visibility"]) { if([inDictionary valueForKey:@"visibility"]!=[NSNull null]) { threadInfo.pollVisibility=[inDictionary valueForKey:@"visibility"]; } } if([[inDictionary allKeys] containsObject:@"yesPercentage"]) { if([inDictionary valueForKey:@"yesPercentage"]!=[NSNull null]) { threadInfo.yesPercentage=[inDictionary valueForKey:@"yesPercentage"]; } } if([[inDictionary allKeys] containsObject:@"noPercentage"]) { if([inDictionary valueForKey:@"noPercentage"]!=[NSNull null]) { threadInfo.noPercentage=[inDictionary valueForKey:@"noPercentage"]; } } if([[inDictionary allKeys] containsObject:@"selectedOption"]) { if([inDictionary valueForKey:@"selectedOption"]!=[NSNull null]) { threadInfo.selectedOption=[inDictionary valueForKey:@"selectedOption"]; } } if([[inDictionary allKeys] containsObject:@"selectedStar"]) { if([inDictionary valueForKey:@"selectedStar"]!=[NSNull null]) { threadInfo.selectedStar=[inDictionary valueForKey:@"selectedStar"]; } } if([[inDictionary allKeys] containsObject:@"choice1Value"]) { if([inDictionary valueForKey:@"choice1Value"]!=[NSNull null]) { threadInfo.choice1Value=[inDictionary valueForKey:@"choice1Value"]; } } if([[inDictionary allKeys] containsObject:@"choice2Value"]) { if([inDictionary valueForKey:@"choice2Value"]!=[NSNull null]) { threadInfo.choice2Value=[inDictionary valueForKey:@"choice2Value"]; } } if([[inDictionary allKeys] containsObject:@"choice3Value"]) { if([inDictionary valueForKey:@"choice3Value"]!=[NSNull null]) { threadInfo.choice3Value=[inDictionary valueForKey:@"choice3Value"]; } } if([[inDictionary allKeys] containsObject:@"choice4Value"]) { if([inDictionary valueForKey:@"choice4Value"]!=[NSNull null]) { threadInfo.choice4Value=[inDictionary valueForKey:@"choice4Value"]; } } if([[inDictionary allKeys] containsObject:@"choice5Value"]) { if([inDictionary valueForKey:@"choice5Value"]!=[NSNull null]) { threadInfo.choice5Value=[inDictionary valueForKey:@"choice5Value"]; } } if([[inDictionary allKeys] containsObject:@"choice1Percentage"]) { if([inDictionary valueForKey:@"choice1Percentage"]!=[NSNull null]) { threadInfo.choice1Percentage=[inDictionary valueForKey:@"choice1Percentage"]; } } if([[inDictionary allKeys] containsObject:@"choice2Percentage"]) { if([inDictionary valueForKey:@"choice2Percentage"]!=[NSNull null]) { threadInfo.choice2Percentage=[inDictionary valueForKey:@"choice2Percentage"]; } } if([[inDictionary allKeys] containsObject:@"choice3Percentage"]) { if([inDictionary valueForKey:@"choice3Percentage"]!=[NSNull null]) { threadInfo.choice3Percentage=[inDictionary valueForKey:@"choice3Percentage"]; } } 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(![contextforThread save:&error]) { NSLog(@"Child error : %@",error); } [context performBlock:^{ NSError *error; if(![context save:&error]) { NSLog(@"%@",error); } }]; }]; } 

websocket //从服务器继续获取数据

  - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message { NSDictionary *responseDict = [message JSONValue]; NSArray *bodyDicta=[responseDict objectForKey:@"body"]; for (int i=0; i<bodyDicta.count; i++) { int responseCode=[[[[responseDict objectForKey:@"body"] objectAtIndex:i ] objectForKey:@"code"] intValue]; [self checkResponseCode:[bodyDicta objectAtIndex: i] indexvalue:responseCode isArray:1]; } 

checkResponseCode

  -(void)checkResponseCode:(NSDictionary *)responseDict indexvalue:(int)code isArray:(int)flag { if(code==3608) { [self manageGroupDetails:responseDict]; } if (code == 3602)// SCROLL ISSUE { [self updateThreadWithSyncDetails:responseDict]; } if (code == 3603) { [self updateCommentWithSyncDetails:responseDict]; } if(code==3607)// SCROLL ISSUE { [self updateSolicitationWithSyncDetails:responseDict]; } } 

updatePollWithSyncDetails

 -(void)updatePollWithSyncDetails:(NSDictionary *)responseDict { BOOL isDuplicate=[[IXDataBaseManager sharedNetworkDataManager] checkForExistenceOfThreadDetailsForThreadID:[responseDict objectForKey:@"poll"]]; if(!isDuplicate) { [[IXDataBaseManager sharedNetworkDataManager] updateThreadEntityWithSyncDetails:detailsDict]; } 

updateSolicitationWithSyncDetails

  -(void)updateSolicitationWithSyncDetails:(NSDictionary *)inDictionary { NSMutableDictionary *paramDict=[NSMutableDictionary dictionaryWithDictionary:inDictionary]; NSString *userEmail=[[NSUserDefaults standardUserDefaults] valueForKey:@"currentUser"]; [paramDict setObject:[NSNumber numberWithBool:NO] forKey:@"isSystemMessage"]; [paramDict setObject:message forKey:@"threadDescription"]; ThreadInfo *threadInfo=[[IXDataBaseManager sharedNetworkDataManager] retrieveSolicitationInfoForThreadID:[inDictionary objectForKey:@"solicitation"]]; [paramDict setObject:threadInfo.threadID forKey:@"thread"]; [[IXDataBaseManager sharedNetworkDataManager] updateThreadEntityWithSyncDetails:paramDict]; } } } 

你看过你附在这个问题上的仪器踪迹吗? 如果你:

  1. 通过线程分隔调用树
  2. 反转呼叫树
  3. 隐藏系统库

你会看到你的所有工作都在主线上完成,大部分时间都花在:

  • -[IXWebSocketDataManager webSocket: didReceiveMessage:]
  • -[IXWebSocketDataManager checkResponseCode: indexvalue: isArray:]
  • -[IXWebSocketDataManager updateSolicitationWithSyncDetails:]

这些都不应该在主线程上。

主线程仅用于用户界面更新。 所有的数据处理都应该在后台运行,不pipe是在NSOperation子类还是GCD块之类。 从主线程获取数据处理,性能将得到改善。

无论你用什么来从networking中检索数据,都会在主线程中返回。 这似乎是这个问题的根源。