0

次の関数があり、*timeStringメモリリークが発生します。私はObjective-C(およびメモリ管理)にかなり慣れてreleaseいませんが、最初にオブジェクトを作成するだけでよいと読みallocました。私alloc *formatterは 、それを に設定したので*timeString、これは私も解放しなければならないということ*timeStringですか?

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

-(NSString *)getDate{

    NSLog(@"getDate");

    NSDateFormatter *formatter;
    NSString *timeString;

    formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd"];

    timeString = [formatter stringFromDate:[NSDate date]];

    [formatter release];

    return timeString;
}

編集:getDate関数が呼び出される場所は次のとおりです。

-(NSString *)getFileName{

    //nameofXMLFile = page_##
    NSString *nameOfFile = [NSString stringWithString:pageTitle];

    //nameOfXMLFile = page_##.DataCheckSheet.xml
    nameOfFile = [nameOfFile stringByAppendingString: @".DataCheckSheet.xml"];

    NSString *dateString = [self getDate];
    dateString = [dateString stringByAppendingString: @"_"];

    NSLog(@"datestring: %@", dateString);

    dateString = [dateString stringByAppendingString:nameOfFile];

    NSLog(@"datestring with append: %@", dateString);

    //nameOfXMLFile = yyyy-MM-dd_page_##.DataCheckSheet.xml
    nameOfFile = dateString;

    return nameOfFile;
}
4

2 に答える 2

1

すでに正しく述べたように、明示的に割り当てられていないすべてのオブジェクトは、定義ごとに「自動解放」されます。つまり、オブジェクトを定義した関数のスコープを離れると、オブジェクトは破棄されます。

オブジェクトをそれより長く有効に保つには、たとえば、オブジェクトをクラスオブジェクトとして保持することにより、オブジェクトに対して「retain」を呼び出します。この「保持」は、「割り当てられた」オブジェクトと同様に、「解放」する必要があります。

問題のオブジェクトへの参照を戻り値として渡すことにより、オブジェクトのスコープは、最初に関数を呼び出した関数に拡張されます...つまり、呼び出し元の関数の最後にオブジェクトが破棄されます、それまでに保持されない限り。

dateStringのアドレスをその変数にコピーし、その文字列を事実上存在から消去したため、nameOfFileは依然として問題のオブジェクトです(これにより、自動解放されます)。混乱を避けるために、理由がない限り、そのような割り当ては避けてください。

つまり、関数呼び出しと戻り値のチェーンがある場合は、適切に解放されない「保持」が行のどこかにないことを確認してください。問題はありません。

于 2012-08-14T18:10:00.577 に答える
0

リークを理解する最善の方法は、Instruments とその「リーク」テンプレートを使用することです。

「リーク」インストゥルメントは、どのオブジェクトがリークされているかを示し、すぐに ObjectAlloc インストゥルメントにジャンプして、リークされたオブジェクトへの保持/解放呼び出しを確認できます。その後、欠落しているリリースがどこにあるかを見つけることができるはずです。

そのままで、コードはメモリ管理に関して問題ないように見えます。ただし、ここで作成された文字列のほとんどは自動解放されます。つまり、外側の自動解放プールが空になると、効果的に解放されます。プールが空になるまで、オブジェクトがリークしているように見える場合があります。

典型的なアプリケーションでは、メイン スレッドには NSApplication/UIApplication によって自動的にインストールされる自動解放プールがありますが、プールはアプリケーションがイベントを受信したときにのみ排出されます (この質問を参照してください) 。

通常の切り離されたスレッド (NSThread または pthread を使用) では、独自のプールをインストールする必要があります (そして定期的にドレインします)。

GCD ディスパッチ キューは、独自の自動解放プールをインストールし、時々それらを排出します。

于 2012-08-14T18:02:20.933 に答える