ARC(自動参照カウント)を使用して、奇妙で(私には見える)単純なメモリリークの状況があります。私は iOS コードで作業していますが、Objective-C 全般に適用する必要があると思います。
パラメータオブジェクトのプロパティをチェックした後、パラメータとして割り当てられたオブジェクトを返す次の関数があります。
- (id) returnParam:(id) obj
{
// Do whatever filtering needed. Return nil for invalid input.
return (NSNumber *)obj;
}
このメソッドを次のようにループで呼び出すと、Instruments でループが終了するまで、割り当てられたメモリが増加し続けることがわかります。
for(int i = 0; i < 1000000; i++)
{
id obj = [[NSNumber alloc] initWithInt:i];
id obj2 = [self returnParam:obj];
NSLog(@"attempt %@", obj2);
}
しかし、returnParam
次のように関数の内容をループに入れると、すべて正常に動作します。メモリーフットスタンプはずっと同じサイズのままです。
for(int i = 0; i < 1000000; i++)
{
id obj = [[NSNumber alloc] initWithInt:i];
// Do whatever filtering needed. Break on invalid input.
id obj2 = obj;
NSLog(@"attempt %@", obj2);
}
フィルタリングの部分を削除したため (基本的に、関数はオブジェクトを呼び出し元に戻すだけです)、同じ状況が続きます。
このシーケンスが保持カウントを想定どおりに減少させない理由を理解できず、可能なすべての組み合わせを__weak
、__unsafe_unretained
あちこちで試しましたが、どれも機能しませんでした。
なぜこれ(パラメーターオブジェクトを返す)が機能しないのかを説明し、この問題の解決策を提案してもらえますか?
PS ところで、Instruments ではメモリ リーク イベントとしてキャプチャされませんが、私が考える状況は明らかなメモリ リークです。