【发布时间】:2013-10-24 14:25:02
【问题描述】:
在我的应用程序中,我经常在后台执行 Core Data 工作。
Testflight 报告了很多关于从 Core Data 获取当前登录环境对象的特定提取的崩溃(我无法复制):
- (Environment *)getActiveEnvironment
{
AppDelegate *ad = [AppDelegate sharedAppDelegate];
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[context setParentContext:ad.managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Environment" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSError *error;
//crash points to this line
NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
Environment *tempE = nil;
if(items.count > 0)
{
for(Environment *e in items)
{
if(!e.token && !e.url)
{
break;
}
Environment *mainContextTv = (Environment *)[ad.managedObjectContext objectWithID:e.objectID];
if(e.activeValue)
tempE = mainContextTv;
}
}
return tempE;
}
这是我从 Testflight 收到的崩溃堆栈:
0 Tower-iSales-Tab 0x002b37b2 testflight_backtrace
1 Tower-iSales-Tab 0x002b2e4a TFSignalHandler
2 libsystem_platform.dylib 0x39144722 _sigtramp
3 CoreData 0x2e1b8cec _perform
4 CoreData 0x2e1c30f4 -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]
5 CoreData 0x2e13477a -[NSManagedObjectContext executeFetchRequest:error:]
6 Tower-iSales-Tab 0x000c7082 -[MySingleton getActiveEnvironment] in MySingleton.m on Line 379
7 Tower-iSales-Tab 0x000c73f8 -[MySingleton getToken] in MySingleton.m on Line 416
8 Tower-iSales-Tab 0x0020c476 -[NetworkManager getPathForViewName:useTimeStamp:timeStamp:index:counter:] in NetworkManager.m on Line 699
9 Tower-iSales-Tab 0x0020aa5a __70-[NetworkManager checkForDataFilesShouldEmptyQueue:isInitialDownload:]_block_invoke167 in NetworkManager.m on Line 415
10 libdispatch.dylib 0x3901b8fa _dispatch_barrier_sync_f_invoke
11 Tower-iSales-Tab 0x0020a33e __70-[NetworkManager checkForDataFilesShouldEmptyQueue:isInitialDownload:]_block_invoke113 in NetworkManager.m on Line 335
12 libdispatch.dylib 0x39017102 _dispatch_call_block_and_release
13 libdispatch.dylib 0x3901c7e4 _dispatch_root_queue_drain
14 libdispatch.dylib 0x3901c9d0 _dispatch_worker_thread2
15 libsystem_pthread.dylib 0x39146dfe _pthread_wqthread
16 libsystem_pthread.dylib 0x39146cc3 start_wqthread
我读过this answer,它建议将队列类型设置为NSPrivateQueueConcurrencyType,而不是NSConfinementConcurrencyType,我可以这样做,但这不是我可以轻松复制的崩溃,所以我想确定会导致这次崩溃。
该答案还建议使用performBlockAndWait 块进行后台提取,但在我的函数中我该怎么做?我需要返回一个Environment 对象,我在整个应用程序中都使用了这个函数。
谢谢
【问题讨论】:
-
-getActiveEnvironment是否在后台线程上运行? -
我只是查看了我的调用,不,它并不总是在调度块中被调用。我认为这可能会导致一些问题。我相信当核心数据已经在后台同步时发生崩溃,我从主线程调用它?但我不确定
-
但它有时是否在后台线程上运行(例如从
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)调用? -
实际上我收回了抱歉,我没有从任何调度块调用它。我存储当前环境有一个局部变量,然后那个在后台。但是,我需要在后台进行获取以避免主上下文中的任何锁定.. 如果这有意义..
-
好的,所以你只从主线程调用
-getActiveEnvironment,将结果存储为局部变量。你确定你以后不会从不同的线程中使用这个对象吗?
标签: ios objective-c core-data nsmanagedobjectcontext nsfetchrequest