0

私は私のアプリでゲームセンターを使用していますが、私はgamecentermanager.mファイルでメモリリークが発生することがわかった:GameCenterManager.mにメモリリークがあるのはなぜですか?

- (void) callDelegate: (SEL) selector withArg: (id) arg error: (NSError*) err 
{ 
assert([NSThread isMainThread]); 
if([delegate respondsToSelector: selector]) 
{ 
    if(arg != NULL) 
    { 
     [delegate performSelector: selector withObject: arg withObject: err]; 
    } 
    else 
    { 
     [delegate performSelector: selector withObject: err]; 
    } 
} 
else 
{ 
    NSLog(@"Missed Method"); 
} 
} 

リークが起きる(コンパイラの警告の三角形に応じて)performSelector(両方のためにそれらの)セレクタは不明です。私が知りたいことが2つあります

1)私はAppleのウェブサイトの例からこれをそのままコピーしていますので、アップルが作成した場合、コードにエラーが表示されませんか?

2)これはどのように修正できますか?

FYI同様、LLMV Compiler 3.1と標準(armv7)アーキテクチャを使用してXcode 4.3.1を使用しています。私もARCを使用しています。

その他の情報が必要な場合は、事前にお知らせください。

答えて

1

ここで問題となるのは、ARCは、-performSelector:withObject:で呼び出しているメソッドのメモリ管理のセマンティクスを知ることができません。 MRRの下では、呼び出しコードがそれに応じて対応することが期待されていたため(例えば、所有オブジェクトであれば戻り値を解放するなど)、問題はありませんでした。しかし、ARCでは、コンパイラはこの情報が正しいことを知るためにはが必要です。私はデフォルトの振る舞いが-performSelector:withObject:であることを覚えていませんが、実際に漏れていない場合には、それを非所有参照として扱うことがあります。

この種のデリゲートパターンを処理する最も簡単な方法は、まだ-respondsToSelector:を使用してから、メソッドを直接呼び出すことです。

if ([_delegate respondsToSelector:@selector(foo:)]) { 
    [_delegate foo:self]; 
} 

あなたの場合、メソッド自体は実際にセレクタが何であるかわかりません。あなたの最善の策は、おそらくこのメソッドを完全に捨て、以前の呼び出し元が代理人と対話することになります。

+0

このメソッドを宣言するNSObjectに "偽の"カテゴリを追加することはできませんか?セマンティクスを "スペルアウト"するだけです... – nielsbot

+0

@nielsbot:問題はメソッドの宣言が欠落しているわけではありません。問題は、宣言に関係なく、動的セレクタを使用して呼び出しているため、コンパイラは呼び出すメソッドを知らないことです。 –

+0

もちろん、あなたは正しいです。気にしないで。 – nielsbot

関連する問題