2

オブジェクトが操作の完了ブロックで参照されている場合、オブジェクトがネットワーク操作を取り消すことが良い考えであるかどうかを理解しようとしています。

例を挙げて説明します。

プロパティを持つUserオブジェクトがあり、次のものがあります。 pictureUser[self fetchPictureFromServer]

- (void)fetchPictureFromServer
{
    NSDictionary *cmdParameters = ...; // set parameters

    __block User *weakSelf = self;  

    [[AppClient sharedClient] sendCommand:@"getpicture" parameters:cmdParameters success:^(AFHTTPRequestOperation *operation, id response) 
     {  
        // success  
        UIImage *downloadedImage = ...; // get image from response  

        weakSelf.picture = downloadedImage; // set image to user's picture property
     }

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        // failed 
    }];

このsendCommandメソッドは を作成 (および にキューに登録NSOperationQueue) し、NSOperation それがやがて を開始しNSURLConnectionてイメージをダウンロードします。操作が正常に完了すると、成功ブロックが呼び出されます。

私が使用してweakSelfいるのは、ブロックに User オブジェクトを保持させたくない (そして、ブロックが解放されないようにする) ためです。
したがって、User dealloc メソッドは次のようになります。

- (void)dealloc
{    
    [[AppClient sharedClient] cancelAllCommandsForSender:self];

    [super dealloc];
}

しかし、deallocメソッドで操作をキャンセルしているのに、ユーザーがdeallocを取得した後EXC_BAD_ACCESSに成功ブロックが呼び出されることがあり、ラインに入るweakSelf.picture = downloadedImage.

なぜそれが起こっているのですか?操作がキャンセルされた場合でも、接続を終了しようとする可能性はありますか?

ブロックでweakSelfではなくselfのみを使用する場合、ブロックはユーザーを保持するため、これは発生しないことを私は知っています。しかし、私はこの動作を望んでいません。フェッチ操作が存在する場合でも、解放されるとすぐにユーザーが dealloc を取得することを望んでいます。

更新: 操作状態がFinished = YESであることに気付きました。私が使用しているライブラリでは、操作が終了したときに成功ブロックをすぐに実行するのではなく、成功ブロックをメイン キューにディスパッチ_非同期しているようです。


1. ユーザーが画像をフェッチ -> 操作が作成される2. 操作が終了 -> 成功ブロックをディスパッチ_async
(まだ実行されていない)
3. 成功ブロックが実行される前に、ユーザーの割り当て解除 -> すべての操作をキャンセル(ただし、isFinished 状態であるため、step1 からの操作ではありません)
4. これで、成功ブロックが実行されます -> ユーザーを参照しようとすると、EXC_BAD_ACCESS が返されます。

これを解決する方法はまだわかりません..

4

1 に答える 1

2
[[AppClient sharedClient] sendCommand:@"getpicture" parameters:cmdParameters success:^(AFHTTPRequestOperation *operation, id response) 
     {  
       if(!operation.isCancelled)
       { 
       // success  
        UIImage *downloadedImage = ...; // get image from response  

        weakSelf.picture = downloadedImage; // set image to user's picture property
       } 
     }
于 2012-07-10T11:51:17.623 に答える