質問

更新:コードを編集しましたが、問題は解決しません...

こんにちは、
これは私の最初の投稿です-私はこの場所が私の質問の多くを解決するための素晴らしいリソースであることを発見しました。通常、私は自分で何かを修正するために最善を尽くしますが、今回は何が間違っているのか本当にわかりませんので、誰かが私を助けてくれることを願っています。
TouchXMLを使用していくつかのxmlファイルを解析するiPhoneアプリを構築しています。 XMLParserクラスがあり、ダウンロードと結果の解析を行います。 XMLParserの同じインスタンスでxmlファイルを複数回解析すると、メモリリークが発生します。 解析スニペットの1つ(関連部分のみ)を次に示します。

for(int counter = 0; counter < [item childCount]; counter++) {  
        CXMLNode *child = [item childAtIndex:counter];
        if([[child name] isEqualToString:@"PRODUCT"]) 
        {
            NSMutableDictionary *product = [[NSMutableDictionary alloc] init];
            for(int j = 0; j < [child childCount]; j++) {
                CXMLNode *grandchild = [child childAtIndex:j];
                if([[grandchild stringValue] length] > 1) {
                    NSString *trimmedString = [[grandchild stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
                    [product setObject:trimmedString forKey:[grandchild name]];
                }
            }

            // Add product to current category array
            switch (categoryId) {
                case 0:
                    [self.mobil addObject: product];
                    break;
                case 1:
                    [self.allgemein addObject: product];
                    break;
                case 2:
                    [self.besitzeIch addObject: product];
                    break;
                case 3:
                    [self.willIch addObject: product];
                    break;
                default:
                    break;
            }
            [product release];
        }

    }  

初めて、xmlを解析し、計測器にリークが表示されないようにします。次回、XMLを解析すると、多くのリーク(NSCFString / NSCFDictionary)が発生しました。
Instrumentsは、リークされたオブジェクトを掘り下げると、 CXMLNode.m内のこの部分を示します。

theStringValue = [NSString stringWithUTF8String:(const char *)theXMLString];
if ( _node->type != CXMLTextKind )
   xmlFree(theXMLString);
}

return(theStringValue);  

私は本当に長い時間を費やし、これを修正するために複数のアプローチを試みましたが、今のところ役に立たないために、おそらく何か重要なものを見逃していますか?

ご協力ありがとうございます!ありがとうございます!

役に立ちましたか?

解決

問題は次の行にある可能性が高い:

[self.mobil addObject:[product copy]];

product のコピーを呼び出すことにより、保持カウント1で新しいNSMutableDictionaryインスタンスを作成しています。ただし、 mobil インスタンスは、コピーの保持をインクリメントします addObject:メッセージを送信するときにカウントされるため、コピーの保持カウントは2になります。一般的に、オブジェクトは独自のオブジェクトメモリを処理するため、 setFoo:または addObject:を使用すると、オブジェクトが自動解放された場合でも、呼び出し直後にオブジェクトを解放する場合でも、オブジェクトを直接渡すことができます。受け渡す必要がある場合、受け渡しているオブジェクトを保持するのは受信者の責任です。

どの変数にもコピーを割り当てなかったため、興味がなくなったため、コピーの保持カウントを減らすために使用できるポインターがありません。 code>はある時点で製品のコピーをリリースします。コピーが保持カウント0に達することはありません。forループの最後にある [product release] ステートメントは、元の product オブジェクト。

代わりに、以下を試して、楽器が幸せかどうかを確認します。

[self.mobil addObject:product];

他のヒント

簡単に言えば、 copy を使用するたびに、 release / autorelease のいずれかを使用する必要があります。

そして、この場合、最初の場所で copy を使用しないのがさらに簡単な答えです。なぜなら、 product の元のバージョンでは何もしていないからです。コピーしました。

自分で問題を修正しました。それはちょっと馬鹿げたものでしたが、誰かが同じものに出くわすかもしれないので、ここに投稿します。

1)可変配列を次のようなインスタンス変数として設定しました:

@interface XMLParser : NSObject {

// ...  
NSMutableArray *mobil;  
// ...  
}   
@property(nonatomic, retain) NSMutableArray *mobil;  
@end  

自分の内部で新しいデータを復元したいたびに:
    self.mobil = nil;
これは私がやりたかったことではなかったので、これはより良いアプローチです:
    [self.mobil removeAllObjects];

2)リークを修正するには、deallocメソッドを次のようにする必要があります(mobilはプロパティとして定義されているため):
    -(void)dealloc {
      [モービルリリース];
      self.mobil = nil;
  }

うーん、それを見つけるのは大変な作業でした-他の誰かが時間を節約できることを願っています:-)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top