Ios 后台抓取比前台抓取导致应用程序冻结
我已经在coredata中实现了后台抓取,但它仍然比正常抓取快了几秒钟。我能为快速抓取做些什么吗?看起来它仍然在前台抓取,不知道代码出了什么问题Ios 后台抓取比前台抓取导致应用程序冻结,ios,objective-c,core-data,Ios,Objective C,Core Data,我已经在coredata中实现了后台抓取,但它仍然比正常抓取快了几秒钟。我能为快速抓取做些什么吗?看起来它仍然在前台抓取,不知道代码出了什么问题 - (void)sr_executeFetchRequest:(NSFetchRequest *)request completion:(void (^)(NSArray *objects, NSError *error))completion { NSString *loginUser=[[NSUserDefaults standardUserDe
- (void)sr_executeFetchRequest:(NSFetchRequest *)request completion:(void (^)(NSArray *objects, NSError *error))completion {
NSString *loginUser=[[NSUserDefaults standardUserDefaults] valueForKey:@"currentUser"];
AppDelegate *sharedDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSPersistentStoreCoordinator *coordinator = [sharedDelegate persistentStoreCoordinator];
NSManagedObjectContext *context = [sharedDelegate managedObjectContext];
NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
backgroundContext.persistentStoreCoordinator = coordinator;
[backgroundContext performBlock:^{
// Fetch into shared persistent store in background thread
NSError *error = nil;
// NSLog(@"BG thread===== ");
NSArray *fetchedObjects = [backgroundContext executeFetchRequest:request error:&error];
[context performBlock:^{
if (fetchedObjects) {
// Collect object IDs
NSMutableArray *mutObjectIds = [[NSMutableArray alloc] initWithCapacity:[fetchedObjects count]];
for (NSManagedObject *obj in fetchedObjects) {
[mutObjectIds addObject:obj.objectID];
// NSLog(@"BG bg===== ");
}
// Fault in objects into current context by object ID as they are available in the shared persistent store
NSMutableArray *mutObjects = [[NSMutableArray alloc] initWithCapacity:[mutObjectIds count]];
for (NSManagedObjectID *objectID in mutObjectIds) {
NSManagedObject *obj = [context objectWithID:objectID];
[mutObjects addObject:obj];
// NSLog(@"BG fg===== ");
}
if (completion) {
NSArray *objects = [mutObjects copy];
completion(objects, nil);
}
} else {
if (completion) {
completion(nil, error);
}
}
}];
}];
}
我在服务器中有一些记录,当后台到前台时,应用服务器将发送所有记录,并且从客户端我将所有数据保存到coredata中。在保存时,我需要检查这些数据是否已经存在,有时我需要在保存之前从数据库中获取一些数据,但在这段时间里,我的应用程序被冻结,只有在所有更新和保存完成后,它才能正常工作
探查器跟踪
保存到数据库
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];
}
UpdatePollWithyncDetails
使用SyncDetails更新Solicitation
你有你的代码行
backgroundContext.persistentStoreCoordinator = coordinator;
…在街区内
在开始performBlock之前,请尝试为MOC设置PSC。您有自己的代码行
backgroundContext.persistentStoreCoordinator = coordinator;
…在街区内
在开始执行performBlock之前,请尝试为MOC设置PSC。首先,您如何知道是提取阻塞了您的UI?你用过这个仪器吗?如果是,追踪在哪里 如果没有,则需要停止,运行仪器,使用时间分析器并找到块。使用跟踪链接更新您的问题,以便下载和查看 不看仪器中的这个问题,你只是在猜测实际问题是什么 更新1 查看您提供的跟踪,我没有看到核心数据在主线程或任何其他线程上占用任何大量时间。我怀疑你在这里追错东西了 上面的代码不会为您节省任何时间。虽然它会将对象加载到NSPersistentStoreCoordinator中,使主NSManagedObjectContext获取对象的速度稍快一些,但这并不重要。根据您的时间跟踪,您没有在主线程上花费SQL 132ms total中的任何时间 即使SQL调用花费了大量时间,它仍然会阻塞主线程,因为在执行获取时锁定了NSPersistentStoreCoordinator 根据您提供的跟踪,您的问题在UI中。大部分时间都花在-[IXInBoxViewController tableView;heightForRowAtIndexPath:]上,这是锁定UI的常用位置。深入您的个人资料,找到昂贵的物品并修复它 问题不在于核心数据。我建议删除此线程代码添加线程不是一个性能解决方案,请返回使用NSFetchedResultsController和UITableViewController,然后分析UI代码并修复缓慢的代码 更新2 我从服务器获取大量数据,并不断节省核心数据。我使用的是NSFetchedResultsController,因此对于每个节省,必须重新加载tableview。现在,我试图同时保存少量数据,这是处理大量核心数据保存请求的正确方法吗 您没有提供任何加载数据或保存数据的代码,因此我无法权威地谈论您是否正确地完成了这些部分 加载的数据量并不重要,只要它加载在后台线程的后台上下文中,我更喜欢使用NSOperation子类并保存到核心数据中。NSFetchedResultsController将执行正确的操作,除非同时显示数据,否则对UI的影响将最小。如果数据正在加载到NSFetchedResultsController中,并且相对脱离屏幕,则不会对性能产生重大影响 运行仪器。当性能成为问题时,这是您的第一步 如果数据加载缓慢,请隔离缓慢的行并对其进行寻址 如果你的保存速度慢,那么就把它分成小块
但首先要分析它。否则,您就是在黑暗中拍摄,只是猜测。首先,您如何知道是抓取阻塞了您的UI?你用过这个仪器吗?如果是,追踪在哪里 如果没有,则需要停止,运行仪器,使用时间分析器并找到块。使用跟踪链接更新您的问题,以便下载和查看 不看仪器中的这个问题,你只是在猜测实际问题是什么 更新1 查看您提供的跟踪,我没有看到核心数据在主线程或任何其他线程上占用任何大量时间。我怀疑你在这里追错东西了 上面的代码不会为您节省任何时间。虽然它会将对象加载到NSPersistentStoreCoordinator中,使主NSManagedObjectContext获取对象的速度稍快一些,但这并不重要。根据你的时间轨迹,你不是 在主线程上花费SQL 132ms总计的任何时间 即使SQL调用花费了大量时间,它仍然会阻塞主线程,因为在执行获取时锁定了NSPersistentStoreCoordinator 根据您提供的跟踪,您的问题在UI中。大部分时间都花在-[IXInBoxViewController tableView;heightForRowAtIndexPath:]上,这是锁定UI的常用位置。深入您的个人资料,找到昂贵的物品并修复它 问题不在于核心数据。我建议删除此线程代码添加线程不是一个性能解决方案,请返回使用NSFetchedResultsController和UITableViewController,然后分析UI代码并修复缓慢的代码 更新2 我从服务器获取大量数据,并不断节省核心数据。我使用的是NSFetchedResultsController,因此对于每个节省,必须重新加载tableview。现在,我试图同时保存少量数据,这是处理大量核心数据保存请求的正确方法吗 您没有提供任何加载数据或保存数据的代码,因此我无法权威地谈论您是否正确地完成了这些部分 加载的数据量并不重要,只要它加载在后台线程的后台上下文中,我更喜欢使用NSOperation子类并保存到核心数据中。NSFetchedResultsController将执行正确的操作,除非同时显示数据,否则对UI的影响将最小。如果数据正在加载到NSFetchedResultsController中,并且相对脱离屏幕,则不会对性能产生重大影响 运行仪器。当性能成为问题时,这是您的第一步 如果数据加载缓慢,请隔离缓慢的行并对其进行寻址 如果你的保存速度慢,那么就把它分成小块
但首先要分析它。否则,您只能在黑暗中进行猜测。使用xCode调试器,您可以在块内添加断点,并检查它们在哪个线程中执行。是的,它们正在执行,我已经记录了值。我的代码有什么问题吗?使用xCode调试器,您可以在块内添加断点,并检查它们在哪个线程中执行。是的,它们正在执行,我已经记录了值。我的代码有什么问题吗?实际上这是在后台线程中完成的,那么为什么主线程会阻塞呢?我很困惑。你有什么解决办法吗?抱歉之前没有注意到这一点,但是你的背景内容的performBlock方法中包含了你的主要上下文。这将阻止您的UII通过引用获取此方法。我的问题是抓取块我的UI,这就是为什么我使用后台抓取,我不知道是否有其他方法。你能帮助我吗?这一点真的被卡住了。实际上这个抓取是在后台线程中完成的,那么为什么主线程会阻塞呢?我很困惑。你有什么解决办法吗?抱歉之前没有注意到这一点,但是你的背景内容的performBlock方法中包含了你的主要上下文。这将阻止您的UII通过引用获取此方法。我的问题是抓取块我的UI,这就是为什么我使用后台抓取,我不知道是否有其他方法。你能帮助我吗?好的,先生,但是我通过评论那些需要保存和获取coredata的方法发现了这个问题。在那之后,它工作得很好,先生,我已经用确切的问题更新了我的问题。好的,先生,我将尝试修复UI问题。我从服务器获取大量数据,并不断节省核心数据。我使用的是NSFetchedResultsController,因此对于每个节省,必须重新加载tableview。现在我正在尝试同时保存少量数据,这是处理大量核心数据保存请求的正确方法吗?请将其转移到一个单独的问题中并关闭此问题。好的,先生,我打开了另一个链接好的,先生,但我通过评论那些需要保存和获取核心数据的方法发现了这个问题。在那之后,它工作得很好,先生,我已经用确切的问题更新了我的问题。好的,先生,我将尝试修复UI问题。我从服务器获取大量数据,并不断节省核心数据。我使用的是NSFetchedResultsController,因此对于每个节省,必须重新加载tableview。现在我正在尝试同时保存少量数据,这是处理大量核心数据保存请求的正确方法吗?请将其转移到另一个问题并关闭此问题。好的,先生,我打开了另一个链接
-(void)updatePollWithSyncDetails:(NSDictionary *)responseDict
{
BOOL isDuplicate=[[IXDataBaseManager sharedNetworkDataManager] checkForExistenceOfThreadDetailsForThreadID:[responseDict objectForKey:@"poll"]];
if(!isDuplicate)
{
[[IXDataBaseManager sharedNetworkDataManager] updateThreadEntityWithSyncDetails:detailsDict];
}
-(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];
}
}
}
backgroundContext.persistentStoreCoordinator = coordinator;