我已经在这个错误上坐了好几个小时了。我在行上获得了EXC_BAD_ACCESS(代码= 2):
[self.downloadQueue addOperation:self.downloadOP];
我知道它必须与内存冲突有关,但我找不到问题。管理OperationQueues的类是一个单例,但我认为这不是问题。
这是我的.h文件的简化版本:
@interface GTMConnectionManager : NSObject{
}
@property (retain) GTMDownloadOperation *downloadOP;
@property (retain) NSOperationQueue *downloadQueue;
// it doesn't make a difference if I add 'nonatomic' to these properties
+ (GTMConnectionManager *)sharedConnectionManager;
-(void)downloadImageData:(NSMutableArray*)p_images andController:(UIViewController*)p_resultsController;
@end
.m文件的重要部分:
#import "GTMConnectionManager.h"
@implementation GTMConnectionManager
@synthesize downloadOP, downloadQueue;
+ (GTMConnectionManager *)sharedConnectionManager
{
static GTMConnectionManager * instance = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
instance = [[super allocWithZone:nil] init];
});
return instance;
}
-(void)downloadImageData:(NSMutableArray*)p_images andController:(GTMResultsListViewController*)p_resultsController{
self.resultsController = p_resultsController;
[self.downloadQueue setMaxConcurrentOperationCount:2];
self.downloadQueue = [[[NSOperationQueue alloc]init]autorelease];
// it doesn't make a difference if I do this with or without 'autorelease'
for (int i = 0; i < [p_images count]; i++) {
GTMGeoImage *tmpImg = [p_images objectAtIndex:i];
self.downloadOP = [[[GTMDownloadOperation alloc]initWithImage:tmpImg]autorelease];
[self.downloadQueue addOperation:self.downloadOP]; //Here's the error
}
}
当我在错误行之前添加断点时,self.downloadQueue和self.downloadOP都会正确保留(不是nil)。
奇怪的是:在这个课程中,我有第二个NSOperationQueue与其他NSOperations一样,以与downloadQueue和downloadOP相同的方式声明和处理。而且他们工作得很好。
是的,GTMDownloadOperation是NSOperation的子类,并且有一个 - (void)main方法。
我现在不知道该怎么办。如果您不知道该错误的原因,我该如何更准确地分析情况? (产品&gt; Analyze不会抱怨该位置的潜在泄漏)。
感谢您的帮助。
答案 0 :(得分:1)
哦,伙计...... 这需要一段时间,但最后我知道问题出现在for循环中。
声明
self.downloadOP = [[[GTMDownloadOperation alloc]initWithImage:tmpImg]autorelease];
在每次迭代中一次又一次地访问变量downloadOP。使用相同的NSOperation似乎会使其retainCount崩溃。
我把它改成了
GTMDownloadOperation *downloadOP = [[GTMDownloadOperation alloc]initWithImage:tmpImg];
它没有错误。傻我。
答案 1 :(得分:1)
你没有在构造函数中调用[super init]?
假设您正在继承NSOperation(或NSObject等...),您可能应该这样做!
答案 2 :(得分:0)
为什么要重新分配并初始化队列? 不可能只是你的单身人士课程吗?
和...
[self.downloadQueue setMaxConcurrentOperationCount:2];
self.downloadQueue = [[[NSOperationQueue alloc]init]autorelease];
第一行在旧队列上执行,然后创建一个没有限制的新行
何时调用第二行(分配新队列),释放旧行(如果有)
试试这个:
if (!downloadQueue){
self.downloadQueue = [[[NSOperationQueue alloc]init]autorelease];
}
[self.downloadQueue setMaxConcurrentOperationCount:2];
并记得添加:
self.downloadQueue = nil;
你的dealloc方法中的(即使它是一个单例,在你的应用程序运行时也不会被调用)
答案 3 :(得分:0)
我认为问题在于您的操作的实施。我建议两个课程:尝试创建一些简单的基于块的操作,只记录hello world并将它们添加到队列中。他们很可能会工作,让你知道队列是否正常运行。然后开始向您的子类添加日志消息,以查看调用哪些方法并正确完成。
这会引导你解决问题。