Асинхронные методы имеют способ размножаться, часто заставляя их вызывающих абонентов также быть асинхронными. Другими словами, если результат метода A зависит от метода B, а methodB является асинхронным, то так же должен быть и метод A.
Таким образом, метод, который содержит код OP, вероятно, должен быть объявлен так:
- (void)getMyTokenChar:(id)someParams completion:(void (^)(NSString *))completion {
// form cardParams with someParams (or maybe they are the same
[sharedClient createTokenWithCard:cardParams completion:^(STPToken *token,NSError *error) {
NSString *tokenChar;
if (token == nil || error != nil) {
tokenChar = [error.localizedDescription UTF8String];
} else {
tokenChar = [token.tokenId UTF8String];
}
if (completion) completion(tokenChar);
}];
}
Звонящий сделает это ...
[theTokenCharObject getMyTokenChar:@"someParams" completion:^(NSString *tokenChar) {
// tokenChar will be a string or an error description here
}];
Вот плохие новости: метод, содержащий этот вызывающий код, вероятно, тоже должен быть асинхронным. Это никогда не заканчивается?
Да, обычно заканчивается в интерфейсе ...
// do something to the UI to say the app is busy, like an activity indicator view
[theTokenCharObject getMyTokenChar:@"someParams" completion:^(NSString *tokenChar) {
// remove the activity indicator view
// show something new to the user: "we got the thing that depends on tokenChar!!"
}];
Существует пара альтернатив, простейший для описания - NSNotificationCenter. Ваш оригинальный метод должен быть (кажется) синхронным ...
- (void)getMyTokenChar:(id)someParams {
// form cardParams with someParams (or maybe they are the same
[sharedClient createTokenWithCard:cardParams completion:^(STPToken *token,NSError *error) {
NSString *tokenChar;
if (token == nil || error != nil) {
tokenChar = [error.localizedDescription UTF8String];
} else {
tokenChar = [token.tokenId UTF8String];
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"TokenGetterDidGetToken" object:tokenChar];
}];
}
Любая другая часть вашего приложения подписывается следующим образом ...
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didGetToken:) name:@"TokenGetterDidGetToken" object:nil];
и должен реализовывать селектор ...
- (void)didGetToken:(NSNotification *)notification {
// notification.object will be the tokenChar
}
Как правило, вам будет лучше проходить мимо блоков. Возьмите пример пользовательского интерфейса, который я привел. Одна часть кода изменит пользовательский интерфейс на занятость, другая отключенная часть должна будет вернуть его обратно.