我正在尝试构建一个下载管理器类,它将所有异步下载(每个操作都有自己的线程)操作打包到 NSOperation 子类中,以便稍后将它们添加到 NSOperationQueue 中。下载管理器类(单例)还公开了一些方法来处理队列并取消符合某些要求的操作。
这些是开始创建类集群(抽象工厂)的步骤,该类集群为不同类型的常见操作(上传、下载、解析等)返回不同类型的 NSOperation。
该类似乎可以很好地处理下载操作,但如果在这些操作中间我调用取消操作的方法,则该操作会成功取消,但应用程序会在稍后的几个操作中崩溃。如果我不取消任何操作,一切都会正常。所有操作均使用 KVO 进行观察。
删除操作的方法如下所示:
- (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>
有人可以给我建议吗?
感谢安德里亚