2017-07-24 4 views
3
- (NSString *)getAuthorizationHeader{ 
    iKMAppDelegate *delegate = (iKMAppDelegate *)[UIApplication sharedApplication].delegate; 
    NSString *header = [NSString stringWithFormat:@"Bearer %@", delegate.appDataObject.oauth2AcessToken]; 
    return header; 
} 

diese Methode eine Warnung in XCode9 bekam wirdiOS11 SDK kann nicht Anwendung Zugriff auf die Delegierten

[UIApplication delegate] must be called from main thread only 

und ich glaube nicht, ein Versand in Haupt-Warteschlange für meine Funktion arbeiten. also, wie man diese Warnung gut repariert?

+0

siehe diese https://stackoverflow.com/questions/45081731/obj-c-uiaapplication-delegate-must-be-called-from-main-thread-only –

+2

"und ich glaube nicht, ein Versand in der Hauptwarteschlange wird arbeite für meine Funktion "- und warum ist das so? –

+0

@mag_zbc, weil ich etwas in meiner Funktion zurückgegeben habe, basierend auf dem Delegaten – ximmyxiao

Antwort

0

Sie können einen Zeiger auf die AppDelegate nehmen, bevor Ihre Hintergrundfunktion aufgerufen wird. Und hol es von diesem Zeiger.

<...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; 
} 

In meinem Beispiel ist ein Singleton.
Wenn Sie Multithread-Zugriff benötigen, bevor ein Delegat nicht festgelegt wird, vergessen Sie nicht die Sperren für den Zugriff (oder markieren Sie das Feld als atomar).

3

Es gibt keine geht um UIApplication Delegierter auf Hauptthread zugreifen, aber Sie können leicht tun mit es 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; 
} 

Was dispatch_async Gegensatz die dispatch_sync Funktion wird bis zum Block warten sie beendet geführt worden ist vor der Rückkehr.

Mit dispatch_sync muss überprüft werden, ob die Funktion nicht vom Hauptthread ausgeführt wird, was zu einem Deadlock führen würde.

Verwandte Themen