【发布时间】:2012-01-25 12:05:58
【问题描述】:
我的代码:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
@autoreleasepool {
// Now on a background thread
// Setup background task
__block UIBackgroundTaskIdentifier bgTask;
void (^finishBackgroundTask)(void) = ^(void) {
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
};
// Start background task
bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:finishBackgroundTask];
// The method below migrates a core data database and takes ages
[MyClass migrateCoreDataStuff];
finishBackgroundTask();
}
});
我得到的错误是NSUnderlyingException = "Fatal error. The database at /var/mobile/Applications/55B83D5F-CCF5-438E-BECA-B97DB5505541/Documents/Blah.sqlite is corrupted. SQLite error code:11, 'database disk image is malformed'";
仅当以下全部为真时才会发生迁移错误: * 迁移在后台线程上 * 迁移作为 UIBackgroundTask 运行 * 我在设备上运行,不是模拟器
我正在运行 iOS 4.3.5,为 iOS 4.0 构建。
【问题讨论】:
-
哎呀...想通了。永远不要从主线程以外的任何地方调用 UIKit 中的任何东西。在这种情况下,我正在启动一个后台任务 (
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:]),从而从后台线程向我的 UIApplication 实例发送消息。这是坏。 -
__block UIBackgroundTaskIdentifier bgTask; void (^finishBackgroundTask)(void) = ^(void) { [[UIApplication sharedApplication] endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; }; bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:finishBackgroundTask];dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ @autoreleasepool { [MyClass migrateCoreDataStuff]; dispatch_async(dispatch_get_main_queue(), finishBackgroundTask); } });
-
这不太可能是根本问题。
beginBackgroundTaskWithExpirationHandler在文档中被特别标记为线程安全。你可能只是在掩盖真正的问题。 -
你说得对,上面的代码实际上是行不通的(我有点草率了)。
标签: objective-c ios core-data ios4 core-data-migration