Как отобразить UIAlertView из блока на iOS?
Каков наилучший способ отображения UIAlertView из блока?
У меня есть следующее действие в моем коде:
- (IBAction)connectWithTwitterClicked:(id)sender {
ACAccountStore * account = [[ACAccountStore alloc]init];
ACAccountType * accountType = [account accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[account requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) {
if (granted == YES){
NSLog(@"Twitter account has been granted");
NSArray * arrayOfAccounts = [account accountsWithAccountType:accountType];
if([arrayOfAccounts count] > 0){
ACAccount * twitterAccount = [arrayOfAccounts lastObject];
NSLog(@"Found twitter Id of [%@]", twitterAccount.username);
// continue on to use the twitter Id
} else {
// no twitter accounts found, display alert to notify user
}
} else{
NSLog(@"No twitter accounts have been granted");
// no twitter accounts found, display alert to notify user
}
}];
}
Я пробовал эти решения до сих пор:
- В любой из двух закомментированных строк, непосредственно создающих и показывающих UIAlertView, это приводит к сбою приложения. Я полагаю, это связано с тем, что блок является асинхронным процессом и не имеет доступа к потоку пользовательского интерфейса для отображения предупреждения
- Создал NSMutableString вне блока, пометил его
__block
установите его в закомментированных строках и затем отобразите после. Аналогичная проблема здесь, когда блок выполняется асинхронно, поэтому во время отображения предупреждения нет никакой гарантии, что NSMutableString был установлен.
Кто-нибудь может предложить решение? Я хочу иметь возможность как-то уведомлять пользователей, чтобы они могли либо не использовать твиттер, либо отключиться и настроить учетную запись в настройках устройства.
Спасибо
2 ответа
Решение
Создайте метод, который показывает представление оповещения, затем выполните его селектор в главном потоке:
- (void)showAlertWithTitle:(NSString *)t
{
[[[[UIAlertView alloc] initWithTitle:t
message:nil
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil
] autorelease] show];
}
Назовите это следующим образом:
[SomeClass dispatchNastyAsyncBlock:^{
// ... do stuff, then
[self performSelectorOnMainThread:@selector(showAlertWithTitle:)
withObject:@"Here comes the title"
waitUntilDone:YES];
}];
Это способ GCD сделать это:
[SomeClass dispatchNastyAsyncBlock:^{
// ... do stuff, then
dispatch_async(dispatch_get_main_queue(), ^ {
[[[[UIAlertView alloc] initWithTitle:t
message:nil
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil
] autorelease] show];
});
}];