現象
NSOperationQueue の addOperation:
実行時に EXC_BAD_ACCESS が発生する現象。しかも NSZombie を有効にするとクラッシュせず普通に動いているように見えてしまう。NSZombie を使い続けていたら発見できなかった現象なので、NSZombie を外しての確認も必須かもしれない。
実装条件など
- NSOperation のサブクラスを自前で実装
- 並列実行モード
- -isConcurrent == YES
- -cancel 対応
だめだった回避策
addOperation:
の実行前に、在オペレーション数が maxConcurrentOperationCount を超過しないようにする判定処理を入れたら落ちなくなった気がしたけれどだめだった。
if (queue.operationCount >= queue.maxConcurrentOperationCount)
return;
[queue addOperation:operation];
結局どうしたか
NSOperation のサブクラスで -cancel
をオーバーライドしたのが悪かったらしい。ただ、NSOperation に対する私の理解が及んでいないため、これで正しいのかは分からないが、とりあえず次に示す方法で例の現象を回避できた。
MyOperation.m
/* このメソッドはオーバーライドしてはいけない
- (void)cancel
{
[super cancel];
// キャンセル時の解放処理等……
}
*/
NSOperation のサブクラスでは
-cancel
メソッドのオーバーライドを一切行わない。
-cancel
をオーバーライドしてはならない、という情報が見当たらなかったので本当にこれで正しいのか自信が無い。ただ、これにより当現象は見られなくなったので、とりあえず現状は良しとしておきたい。。