我的应用程序中有一些长时间运行的启动任务(如从本地数据存储装载Parse对象)。这些任务应该在界面开始出现之前完成。该应用最初是使用故事板创建的,因此在application:didFinishLaunchesWithOptions:
方法结束后界面开始自动显示。我无法阻止主线程,因为Parse SDK会在主线程上触发所有回调函数(因此阻塞导致死锁)。我还需要延迟从应用程序返回:didFinishLaunchesWithOptions:完成设置。所以我做的是:应用程序中的长时间运行任务:didFinishLaunchesWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Dispatch long-running tasks
dispatch_group_t startup_group = dispatch_group_create();
dispatch_group_async(startup_group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Perform some long-running setup here
});
// Run main run loop until startup tasks finished (is it OK to do so?)
while (dispatch_group_wait(startup_group, DISPATCH_TIME_NOW))
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
return YES;
}
是否正确使用NSRunLoop?有没有什么潜在的警告?你能提出更优雅的(最好是GCD)解决方案吗?
UPDATE:
- 加载解析对象从本地数据存储(即从装载SSD微小文件)不只要操作从web装载的东西。延迟几乎没有引人注意,但足以触发
warnBlockingOperationOnMainThread
,因此UX不是问题。 - 真正的问题是由于在正常主循环上旋转另一个主循环而导致的(偶尔)崩溃,有时会导致重新进入代表方法,这显然不是线程安全的。
- 启动屏幕的原因介绍是一个明显的解决方案,但我正在寻找一个更简单和优雅的东西。我有一个感觉它存在。
而是延迟'didFinishLaunchingWithOptions的回报:'我想呈现出装载图,告诉什么应用程序在主窗口的前面做的是一个更好的主意用户。 – KudoCC 2015-04-03 09:53:52
旋转运行循环可能存在的问题:http://stackoverflow.com/questions/26371462/weird-crash-when-launching-app-from-notification-center – 2015-04-06 14:09:37
您的解决方案可以在该方法中进行小改动。我想你的加载对象是应用程序中共享状态的一部分。加载操作完成后,您可以简单地添加一个'ready'标志,并将其设置为'true'。应用程序的其他部分可以重复检查此标志(使用NSTimer),也可以使用KVO或通知来获得完成通知。当涉及UI时,试图强制同步操作通常不是一个好主意。 – allprog 2015-04-09 12:25:36