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 ではありません)。

奇妙なことに、このクラスには、downloadQueue および downloadOP と同じ方法で宣言および処理される他の NSOperations を持つ 2 番目の NSOperationQueue があります。そして、それらは完璧に機能します。

はい、GTMDownloadOperation は NSOperation の子クラスであり、-(void)main メソッドがあります。

私は今何をすべきかわかりません。そのエラーの理由がわからない場合、状況をより正確に分析するにはどうすればよいですか? (Product > Analyze は、その位置での潜在的なリークについて文句を言いません)。

ご協力いただきありがとうございます。

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

なぜ再割り当てしてキューを初期化するのですか? それはあなたのシングルトンクラスの1つだけではありませんか?

と...

[self.downloadQueue setMaxConcurrentOperationCount:2];
self.downloadQueue = [[[NSOperationQueue alloc]init]autorelease];

最初の行は古いキューで実行され、次に制限のない新しいキューを作成します

いつ 2 番目の行を呼び出しますか (新しいキューを割り当てます) 古いものを解放しますか (もしあれば)

これを試して:

if (!downloadQueue){
    self.downloadQueue = [[[NSOperationQueue alloc]init]autorelease];
}
[self.downloadQueue setMaxConcurrentOperationCount:2];

忘れずに追加してください:

self.downloadQueue = nil;

dealloc メソッドで (シングルトンであっても、アプリの実行中には呼び出されません)

于 2012-09-25T09:50:04.130 に答える
0

問題はあなたの操作の実装にあると思います。2 つのコースをお勧めします。Hello World をログに記録し、それらをキューに追加するだけの単純なブロック ベースの操作を作成してみてください。ほとんどの場合、それらは中華鍋であり、キューが機能していることを知らせます。次に、ログ メッセージをサブクラスに追加して、どのメソッドが呼び出され、適切に終了するかを確認します。

これにより、問題が発生するはずです。

于 2012-09-25T11:48:28.087 に答える