2

从块中显示 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
        }
    }];
}

到目前为止,我已经尝试过这些解决方案:

  1. 在 2 条注释行中的任何一条上,直接创建并显示 UIAlertView,这会使应用程序崩溃,我相信这是由于块是异步进程并且无法访问 UI 线程来显示警报
  2. 在块外创建一个 NSMutableString ,用 标记它 __block,将其设置在注释行上,然后在之后显示。这里的类似问题是块异步运行,因此在显示警报时不能保证 NSMutableString 已设置。

任何人都可以提出解决方案吗?我希望能够以某种方式通知用户,以便他们不能使用 twitter,或者在设备设置中设置一个帐户。

谢谢

4

2 回答 2

11

这是执行此操作的 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];
    });
}];
于 2013-01-03T19:37:59.007 回答
8

创建一个显示警报视图的方法,然后在主线程上执行其选择器:

- (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];
}];
于 2013-01-03T11:23:59.637 回答