- (NSString *)getAuthorizationHeader{
iKMAppDelegate *delegate = (iKMAppDelegate *)[UIApplication sharedApplication].delegate;
NSString *header = [NSString stringWithFormat:@"Bearer %@", delegate.appDataObject.oauth2AcessToken];
return header;
}
此方法将在XCode9中收到警告
[UIApplication delegate] must be called from main thread only
我不认为主队列中的调度将适用于我的功能。那么如何很好地解决这个警告?
答案 0 :(得分:5)
在主线程上无法访问UIApplication的委托,但您可以使用dispatch_sync
- (NSString *)getAuthorizationHeader{
__block iKMAppDelegate *delegate;
if([NSThread isMainThread]) {
delegate = (iKMAppDelegate *)[UIApplication sharedApplication].delegate;
} else {
dispatch_sync(dispatch_get_main_queue(), ^{
delegate = (iKMAppDelegate *)[UIApplication sharedApplication].delegate;
});
}
NSString *header = [NSString stringWithFormat:@"Bearer %@", delegate.appDataObject.oauth2AcessToken];
return header;
}
与dispatch_async
相反,dispatch_sync
函数将等到它传递的块完成后再返回。
使用dispatch_sync
,有必要检查是否未从主线程执行该函数,这会导致死锁。
答案 1 :(得分:0)
在调用后台函数之前,您可以使用指向AppDelegate的指针。从指针中获取它。
<...Main thread in app...>
[[MyDelegateHolder holder] setDelegate: (iKMAppDelegate *)[UIApplication sharedApplication].delegate];
<...RunBackground task...>
[[MyDelegateHolder holder].delegate methodCall];
<...In MyDelegateHolder's delegate method ....>
- (iKMAppDelegate*)delegate
{
if (self.delegate == nil)
{
<Assert or...>
runSyncOnMainThread(^(){//you should get delegate in sync method from the main thread
self.delegate = (iKMAppDelegate *)[UIApplication sharedApplication].delegate;
});
}
return self.delegate;
}
在我的例子中,MyDelegateHolder
是一个单身人士
如果您需要多线程访问,在委托不设置之前,请不要忘记访问锁(或将字段标记为原子)。