I'm unsure why the didFinishLaunching
return status is dependent upon the success of your completion handler as you're not apparently even considering launchOptions
. I'd hate to see you put an synchronous call (or more accurately, use a semaphore to convert an asynchronous method into a synchronous one) here, as it will slow down the app and, if its slow enough, you risk being killed by the watch dog process.
Semaphores are one common technique for making an asynchronous process synchronous:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
__block BOOL successful;
SPRManagedDocument *document = [SPRManagedDocument sharedDocument];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[document prepareWithCompletionHandler:^(BOOL success) {
successful = success;
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
return successful;
}
But, upon further review of what prepareWithCompletionHandler
is doing, it's apparently calling methods that dispatch their own completion blocks to the main queue, so any attempts to make this synchronous will deadlock.
So, use asynchronous patterns. If you want to initiate this in the didFinishLaunchingWithOptions
, you can have it post a notification:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
__block BOOL successful;
SPRManagedDocument *document = [SPRManagedDocument sharedDocument];
[document prepareWithCompletionHandler:^(BOOL success) {
successful = success;
[[NSNotificationCenter defaultCenter] postNotificationName:kDocumentPrepared object:nil];
}];
return successful;
}
And you can then have your view controller addObserverForName
to observe this notification.
Alternatively, you can move this code out of the app delegate and into that view controller, eliminating the need for the notification.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…