NSOperationサブクラスですべての非同期ダウンロード(すべてのオペレーションに独自のスレッドがあります)操作をパケット化し、後でNSOperationQueueに追加するダウンロードマネージャークラスを構築しようとしています。ダウンロードマネージャクラス(シングルトン)は、いくつかの要件に合致するキュー上で動作し、操作を取り消すいくつかのメソッドも公開しています。
これは、一般的な操作の種類(アップロード、ダウンロード、解析など)ごとに異なる種類のNSOperationを返す種類のクラスター(抽象ファクトリ)の作成を開始する手順です。
クラスはダウンロード操作ではうまくいくように見えますが、操作の途中で操作をキャンセルするメソッドを呼び出すと、操作は正常にキャンセルされますが、後でアプリケーションがクラッシュすることはほとんどありません。私はすべての操作をキャンセルしない場合、すべて正常に動作します。すべての操作はKVOを使用して観察されます。 操作を削除する方法は以下のようになります。NSOperationQueueからNSOperationをキャンセルするとクラッシュする
- (void) cancelDownloadOperationWithID:(NSString *)aUUID{
@synchronized(self){
[self.dowloadQueue setSuspended:YES]; //downloadQueue is an NSOperationQueue
NSArray * downloadOperations = [self.dowloadQueue operations];
NSPredicate * aPredicate = [NSPredicate predicateWithFormat:@"SELF.connectionID == %@",aUUID]; //SELF is the signleton instance of the download manager
NSArray * filteredArray = [downloadOperations filteredArrayUsingPredicate:aPredicate];
if ([filteredArray count]==0) {
[self.dowloadQueue setSuspended:NO];
return;
}
[filteredArray makeObjectsPerformSelector:@selector(cancel)];
NSLog(@"Cancelled %d operations",[filteredArray count]);
[self.dowloadQueue setSuspended:NO];
}
}
クラッシュログはかなり不可解ですが、BAD_EXC_ACCESS(おそらくゾンビ)で、私はARCの下だと気づきます。
0x00a90ea8 <+0393> jle 0xa90d9f <____NSOQSchedule_block_invoke_0+128>
0x00a90eae <+0399> mov -0x38(%ebp),%ecx
0x00a90eb1 <+0402> mov -0x34(%ebp),%esi
0x00a90eb4 <+0405> mov (%esi,%ecx,1),%ecx
0x00a90eb7 <+0408> mov -0x40(%ebp),%esi
0x00a90eba <+0411> cmpb $0x0,(%ecx,%esi,1)
0x00a90ebe <+0415> jne 0xa90d9f <____NSOQSchedule_block_invoke_0+128>
0x00a90ec4 <+0421> mov (%edi,%eax,1),%esi
0x00a90ec7 <+0424> mov (%esi,%edx,1),%ebx
0x00a90eca <+0427> mov %ebx,-0x2c(%ebp)
0x00a90ecd <+0430> mov -0x44(%ebp),%ebx
0x00a90ed0 <+0433> cmpl $0x50,(%esi,%ebx,1)
0x00a90ed4 <+0437> mov %edi,%ebx
0x00a90ed6 <+0439> jne 0xa90e96 <____NSOQSchedule_block_invoke_0+375>
0x00a90ed8 <+0441> mov -0x48(%ebp),%ebx
0x00a90edb <+0444> cmpb $0x0,(%esi,%ebx,1)
0x00a90edf <+0448> mov %edi,%ebx
0x00a90ee1 <+0450> je 0xa90e96 <____NSOQSchedule_block_invoke_0+375>
いくつか私にそれについての提案を与えることができますか?
Thanx Andrea
これは私にとって非常に奇妙な行動のように思えるが、なぜキューがまだ開始されていない操作を続けるだろう、/キューに入れられましたか?ありがとう、それは私のクラッシュを修正しました。 –
私にとっても、意味がありますが、私たちはデキューしていません。 – Andrea