0

XMLドキュメントの解析にはNSXMLParserを使用しています。私は(とりわけ)次の機能を持っています:

- (void) parserDidStartDocument:(NSXMLParser *)parser {

    // Init tempString
    tempString = [NSMutableString string];

}    
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

        // save gained data for element "date"
        if ([elementName isEqualToString:@"date"])
            [entryDict setObject:[tempString copy] forKey:kXMLDictDateKey];

        [tempString setString:@""];
    }


    //
    // Character Handling
    //
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
        [tempString appendString:[[XMLParser alloc] stripUnwantedStringChars:string]]; //Just strips tabs and linebreaks and the returns the string
    }

tempStringは、次のプロパティを持つインスタンス変数です。

@property (nonatomic, retain) NSMutableString *tempString;

tempStringは、便利なメソッドで開始されるため、deallocで解放する必要はありません。したがって、自動解放プールに自動的に割り当てられます。また、alloc、initアプローチを使用して次のことを試しましたが、同じ結果になりました。これが私がしたことです:

1.)機器を使用してプロジェクトを実行し、起動直後にリークを検索します。リークはありません。2.)XMLパーサーを1回実行し、リークがないか確認します。ありません。3.)XMLパーサーを再度実行します。これで、突然、[entryDict setObject:[tempString copy] forKey:kXMLDictDateKey];リークのある行が表示されます。

私はこれらのメモリリークを何時間も調べてきましたが、何を忘れましたか?さらにコードが必要な場合はお知らせください。私の問題はこれらの行のどこかにあると思います。

追伸 私のチェックでは、パーサー(デリゲート)呼び出しの間に「dealloc」メソッドが呼び出されることが示されています。したがって、パーサーは1回だけでなく、実際には2回ロードされると思います。

4

4 に答える 4

3

あなたの電話番号:

tempString = [NSMutableString string];

実際には、プロパティ (ラッパー) とretain.

代わりにこれを行う必要があります。

self.tempString = [NSMutableString string];

それ以外の場合は、自動解放されたオブジェクトに ivar を直接設定するだけです。

どこかにリークがあるだけでなく、上記のコードはある時点で興味深いクラッシュを引き起こします。

于 2010-01-30T23:58:50.097 に答える
1

tempString への割り当てで、あなたが何をしたのかを把握しようとしています。あなたがこれをしているなら:

self.tempString = [NSMutableString string];

次に、dealloc で tempString を解放する必要があります。自動解放されていますが、セッターはそれを保持しています。

于 2010-02-01T02:34:56.953 に答える
1

コードの他のバグは次のとおりです。

[tempString appendString:[[XMLParser alloc]
    stripUnwantedStringChars:string]];

これにより、新しいものが割り当てられ、XMLParser決して削除されません。

于 2010-01-31T00:10:05.237 に答える
0

まず第一に、自動解放された変更可能な文字列は、parserDidStartDocument から戻った直後に解放されるはずなので、これは実際にクラッシュするはずだと思います。そうではないことは一種の懸念事項であり、プロパティが保持されていないのに保持されていると主張することで、プロパティの定義に嘘をついています。

ただし、Leaks が伝えているのは、文字列のコピーがリークされたということです。Leaks は、リークしているオブジェクトが割り当てられた場所を示しますが、それはリークの原因ではありません。リークの原因は、後でその文字列を適切に解放する必要があるコードの行です。Leaks は存在しないコードを指すことができないため、正しく解放されていないオブジェクトを作成したものだけが表示されます。

この場合、あなたが見逃しているのは、配列が自動解放されたオブジェクトを保持する必要があるということだと思います-だからあなたは言いたいです:

[entryDict setObject:[[tempString copy] autorelease] forKey:kXMLDictDateKey];

Copy もコピーを保持するためです (alloc/init と同様)。

于 2010-01-30T23:01:40.073 に答える