0

我已经坐在这个错误上几个小时了。我得到一个 EXC_BAD_ACCESS (code=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 方法。

我不知道现在该怎么办。如果您不知道该错误的原因,我该如何更准确地分析情况?(产品 > 分析不会抱怨该位置的潜在泄漏)。

谢谢你的帮助。

4

4 回答 4

1

哦,伙计……这花了一段时间,但最后我知道问题出在 for 循环中。

该声明

self.downloadOP = [[[GTMDownloadOperation alloc]initWithImage:tmpImg]autorelease];

在每次迭代中一次又一次地访问变量 downloadOP。使用相同的 NSOperation 似乎会使它的 retainCount 崩溃。

我把它改成

GTMDownloadOperation *downloadOP = [[GTMDownloadOperation alloc]initWithImage:tmpImg];

它可以正常工作。傻我。

于 2012-09-26T06:11:51.327 回答
1

您没有在构造函数中调用 [super init] 吗?

假设您正在继承 NSOperation(或 NSObject 等),您可能应该这样做!

于 2016-01-12T09:17:44.740 回答
0

我相信问题出在您的操作执行中。我建议两门课程:尝试创建一些简单的基于块的操作,这些操作只记录 hello world 并将它们添加到队列中。他们很可能会炒锅,让您知道队列正常工作。然后开始向您的子类添加日志消息,以查看哪些方法被调用并正确完成。

这应该会导致您遇到问题。

于 2012-09-25T11:48:28.087 回答
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 方法中(即使它是单例,并且在您的应用程序运行时不会被调用)

于 2012-09-25T09:50:04.130 回答