2

私は保持サイクルを完全に理解していないと思うので、しばらくの間この問題に苦労してきました。私はこれにまったく慣れていないので、それについてもっと学ぼうとしています。

次のコードで EXC_BAD_ACCESS メッセージを取得しています。

self.successBLock(); を使用するだけで保持サイクルに関する 2 つの警告が表示されるため、weakSelf の使用を開始しました。正確な警告は次のとおりです。

Capturing 'self' strongly in this block is likely to lead to a retain cycle

多分私は弱いものを使うことさえ気にすべきではありませんが、私はこれについて確信が持てません.

これは、ブロックでweakSelfを使用する部分です:

__weak Request *weakSelf = self;

[_operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    weakSelf.successBlock(operation.response, responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    weakSelf.failureBlock(operation.response, error);
}];

これは、ブロック プロパティを割り当てる方法です。

typedef void (^successBlock)(NSHTTPURLResponse *response, id responseObject);
typedef void (^failureBlock)(NSHTTPURLResponse *response, NSError *error);

@property (nonatomic, copy) successBlock successBlock;
@property (nonatomic, copy) failureBlock failureBlock;
4

2 に答える 2

9

__weak参照がnil指すオブジェクトが割り当て解除されると、参照が設定されます。したがってRequest、完了ブロックが呼び出されたときにオブジェクトの割り当てが既に解除されている場合はweakSelfnil. その場合weakSelf.successBlock、NULL ポインターに評価され、それがクラッシュの原因となっています。

次のパターンは、この問題を回避します。

[_operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    Request *strongSelf = weakSelf;
    if (strongSelf) {
        strongSelf.successBlock(operation.response, responseObject);
    }
} ...

strongSelfオブジェクトがすでに割り当て解除されているnil場合になります。Requestそれ以外の場合、強参照により、ブロックの実行中にオブジェクトの割り当てが解除されないことが保証されます。

一方、Request完了ブロックが呼び出されるまでオブジェクトを存在させたい場合は、弱参照を使用しないでください。

于 2013-05-08T14:00:53.350 に答える