iOS11 SDK无法访问应用程序的代理

时间:2017-07-24 08:05:46

标签: ios xcode

- (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

我不认为主队列中的调度将适用于我的功能。那么如何很好地解决这个警告?

2 个答案:

答案 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是一个单身人士 如果您需要多线程访问,在委托不设置之前,请不要忘记访问锁(或将字段标记为原子)。