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 に答える