2009-07-17 2 views
0

Ich habe weit und breit nach seiner Bedeutung gesucht. Meine Vermutung ist, dass ich irgendwie einen korrupten Stapel habe. Ich bekommeWas ist tiny_free_list_add_ptr?

winzige _ free_ list_ ADD_ ptr

am 16. Aufruf der Zeile, die sagt:

NSDateFormatter *theFormatter = [[NSDateFormatter alloc] init]; 

Was ist die Ursache des Problems? Habe ich Recht damit zu denken, dass ich einen korrupten Stapel habe?

- (NSString *)formatDate:(NSString *)uglyDate withFormat:(NSString *)theFormat { 

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSDateFormatter *theFormatter = [[NSDateFormatter alloc] init]; 
    [theFormatter setDateFormat:theFormat]; 

    NSDate *realDateUgly = [NSDate dateWithNaturalLanguageString:uglyDate]; 
    if (realDateUgly == nil) 
     realDateUgly = [NSDate dateWithString:uglyDate]; 

    NSString *prettyDate = [[NSString alloc] initWithString:[theFormatter stringFromDate:realDateUgly]]; 

    [pool drain]; 
    [pool release];  
    [theFormatter release]; 
    return prettyDate; 

} 

Antwort

2
  1. Ich bezweifle, dass Sie hier einen Pool brauchen.
  2. Sie sind über die Freigabe des Pools. drain ist das gleiche wie release in Nicht-GC-Code. (release ist im GC-Code genauso redundant, weil es dann ein No-Op ist.)
  3. Sie sind undicht prettyDate. Du solltest es automatisch freigeben. (Natürlich, das nicht mit dem Pool um es funktionieren wird, das ist ein guter Grund zu töten, dass Pool.)

Sobald Sie die Memory Management Programming Guide for Cocoa überprüfen und reparieren Ihre Speicher-Management-Probleme, sollten Sie entweder finden das Problem behoben oder zumindest besser nachvollziehen zu können.

Wenn das Problem weiterhin besteht, nachdem Sie die Speicherverwaltung repariert haben, bearbeiten Sie Ihre Frage so, dass sie den vollständigen Stack-Trace enthält.

+0

Vielen Dank für Ihre schnelle Antwort. Ich hätte nicht so schnell über die Autorelease-Sektion blättern sollen. Ich nahm deinen Rat und entfernte den Pool. Wie für schönes Datum, änderte ich es zu diesem: NSString * prettyDate = [theFormatter stringFromDate: realDateUgly]; Das Problem besteht nicht mehr in dieser Funktion, aber anderswo. Ich werde den Memory Management Programming Guide für Cocoa studieren. Danke noch einmal. –

+0

Eigentlich noch eine Sache: Ich würde immer noch gerne wissen, was tiny_free_list_add_ptr ist. Nur neugierig. :) –

+0

Eine interne Funktion, vermutlich innerhalb der Malloc-Maschinerie (die mit der freien Liste zu tun hat). –

0

Ich nehme an, Sie stürzen in tiny_free_list_add_ptr. Wenn dies der Fall ist, klingt tiny_free_list_add_ptr wie eine Funktion, die eine malloc-Implementierung verwenden würde, um Speicherblöcke auf dem Heap zu verfolgen. Wenn der Heap beschädigt ist, würde ich erwarten, dass eine solche Funktion abstürzt.

Sie sind wahrscheinlich dabei, etwas loszulassen (wie der Auto Release Pool, auf den Peter hingewiesen hat) hier oder in einer anderen Methode.

Sie sollten versuchen, mit dem Umgebungsvariablenset NSZombiesEnabled ausgeführt werden. Siehe http://developer.apple.com/technotes/tn2004/tn2124.html#SECFOUNDATION

0

ich bereit wäre, das Problem zu wetten, ist dies:

[pool drain]; 
[pool release]; 

In einer nicht-GC-App, drain 'verhält sich' wie Release. "Behaves" ist das in der Dokumentation verwendete Wort, aber die Dokumentation ist ein wenig mehrdeutig, wenn Sie pedantisch präzise sein müssen, was genau passiert, wenn -drain aufgerufen wird. Für mich zumindest "benimmt" sich ein bisschen Spielraum, besonders im Vergleich zu "drain ist genau das selbe wie release", was viel weniger Interpretationsspielraum lässt.

Der Grund, warum ich das aufbringe, ist "Was passiert mit dem Autorelease-Pool, nachdem --drain heißt?" Ich konnte in der Dokumentation zu dieser Frage keine befriedigende Antwort finden. An verschiedenen Stellen impliziert die Dokumentation, dass sich -Drain im GC-Modus als "Hinweis auf das GC-System" verhält und objc_collect_if_needed() aufruft. Ich konnte nichts finden, das explizit besagt, dass ein Autorelease-Pool, der eine "Abmeldung" gesendet hat, im GC-Modus "nicht mehr gültig" ist (dh etwas, das sich so verhält, als ob es eine Freigabenachricht gesendet hätte). Nichts, was ich in der Dokumentation finden konnte, scheint es ausdrücklich zu verbieten, ein instanziiertes NSAutoreleasePool-Objekt eine -drain-Nachricht mehrfach zu senden, wenn es unter GC ausgeführt wird.

Die nächste Sache, die ich finden konnte, war in der Nähe der Spitze der NSAutoreleasePool-Klasse Dokumentation: "Entleerung eines Pools hat letztlich den Effekt der Freigabe". Das hilft uns hier allerdings wenig. Der Kontext, aus dem dies genommen wurde, ist nicht sehr klar, ob dies für GC- oder Nicht-GC-Modus gilt oder nicht. In jedem Fall ist es mit "ultimativ" qualifiziert, was durch pedantische Wörterbuchdefinition "nicht jetzt, aber letztendlich" bedeutet. Ohne die "ultimate" Qualifikation ist es unzweideutig, ob das instanziierte Autorelease-Pool-Objekt freigegeben wurde oder nicht, und durch Induktion, dass das Senden zusätzlicher Nachrichten an diesen Zeiger zu undefiniertem Verhalten führt.

Also, da ich auf nichts autoritatives hinweisen kann, um dies zu untermauern, ist es meiner Meinung nach, dass sich -Drain im Nicht-GC-Modus 'genau' wie -release verhält (höchstwahrscheinlich intern als [self release] implementiert)). Wenn dies der Fall ist, haben Sie das NSAutoreleasePool-Objekt "freigegeben". In diesem Fall wird das Problem verschwinden, wenn Sie eine der beiden Anweisungen auskommentieren.

+0

Sehr gründlich. Ich mag es. –