1

ユーザー アクションがオンライン リソースへの接続を試みるアプリがあります。接続プロセスは thirdPartySDK によって行われ、成功または失敗は非同期的に通知されます。これは、いずれかの方法で通知を投稿するように構成した appDelegate によって処理されます。(つまり、Dropbox スタイル)。

以下では、失敗を想定して、操作が実行された回数だけ UIAlertViewが呼び出されます。つまり、接続を繰り返しテストして失敗した場合、最初にブロックが 1 回呼び出され、2 回目にブロックが 2 回呼び出され、3 回目に 3 回呼び出されます。またはキューから削除されます。

if (!opQ) {
    opQ = [[NSOperationQueue alloc] init];
}

[[NSNotificationCenter defaultCenter] addObserverForName:LINK_NOTIFICATION_FAILURE object:nil queue:opQ usingBlock:^(NSNotification *aNotification) {

    dispatch_async(dispatch_get_main_queue(),
     ^{
        [[[UIAlertView alloc] initWithTitle:@"Network_Account_Not_Linked" message:@"Your_attempt_to_link_your_account_ended_unsuccessfully" 
          delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];

        [[NSNotificationCenter defaultCenter] removeObserver:self];

     });

}];

問題はaddObserverForName:object:queue:usingBlock:にあるようです。addObserver:selector:name:object:でテストしましたが、これは正常に動作します (通知ごとに 1 つのセレクターが実行されます)。ブロックを使用すると、より便利になり、コードが読みやすくなり、ローカル変数にアクセスできるようになります。これが私の動機です。

[opQ cancelAllOperations]を NSBlockOperation スレッドと dispatch_async で試しました (デバッガーによると、 opQはその時点で「範囲外」です)。また、同様の失敗した結果で[NSOperationQueue mainQueue]を使用しました。さらに、通知に登録する前に、新しいopQから始めてみました... nada。

複数の通話が発生するのはなぜですか? ブロックを使用したより良いアプローチはありますか?

4

1 に答える 1

3

使用している方法のAppleドキュメントには次のように書かれています。

オブザベーションの登録を解除するには、このメソッドによって返されたオブジェクトをremoveObserver:に渡します。addObserverForName:object:queue:usingBlock:で指定されたオブジェクトの割り当てが解除される前に、removeObserver:またはremoveObserver:name:object:を呼び出す必要があります。

言い換えれば、selfオブザーバーを削除するときに単に通過することはできません。

試す:

__block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:LINK_NOTIFICATION_FAILURE object:nil queue:opQ usingBlock:^(NSNotification *aNotification) {

dispatch_async(dispatch_get_main_queue(),
 ^{
    [[[UIAlertView alloc] initWithTitle:@"Network_Account_Not_Linked" message:@"Your_attempt_to_link_your_account_ended_unsuccessfully" 
      delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];

    [[NSNotificationCenter defaultCenter] removeObserver:observer];

 });
}];
于 2012-05-21T17:01:04.497 に答える