2012-04-02 10 views
2

ich eine Methode haben, die dann eine Zeichenfolge erstellt anhängt zusätzliche Saiten auf sie:Objective-C NSString malloc Fehler

-(NSString*)returnDetails { 
    NSString *details = [[NSString alloc] init]; 

    details = [details stringByAppendingString:url]; 
    details = [details stringByAppendingString:@" : "]; 
    details = [details stringByAppendingString:author]; 

    return [details autorelease]; 
} 

Und ich diesen Fehler:

iphoneapp_1(66508,0xacd9e2c0) malloc: *** error for object 0x6b9eb80: pointer being freed was not allocated

Wenn ich Ändern Sie es in

NSString *details = [NSString string]; 

und entfernen Sie den Autorelease-Aufruf, dann funktioniert es. Ich möchte nur verstehen, warum das funktioniert und meine ursprüngliche Methode nicht?

Antwort

3

Die NSString ‚s Methode stringByAppendingString: ein Objekt zurückgibt, die bereits Autoreleased wird. Wenn Sie also [details autorelease] von Ihrer Methode zurückgeben, wird dieses Objekt noch einmal freigegeben. Geben Sie einfach details zurück.

Sie haben auch einen Speicherverlust dort, weil Sie die Zeichenfolge, die Sie am Anfang der Methode zugewiesen haben, nie freigegeben haben. Versuchen Sie diesen Code:

-(NSString*)returnDetails { 
    NSString *details = [NSString string]; 
    details = [details stringByAppendingString:url]; 
    details = [details stringByAppendingString:@" : "]; 
    details = [details stringByAppendingString:author]; 

    return details; 

}

+0

Dank Kumpel, ich verstehe jetzt :) – harrynorthover

3

Wenn Sie

rufen
details = [details stringByAppendingString:NSString*]; 

erstellen Sie ein neues Objekt, das bereits als Autorelease markiert. Um das zu erreichen, was Sie wollen, können Sie einfach tun:

-(NSString*)returnDetails { 
    NSMutableString *details = [[NSMutableString alloc] init]; 

    [details appendString:url]; 
    [details appendString:@" : "]; 
    [details appendString:author]; 

    return [details autorelease]; 
} 
1

stringByAppendingString: gibt Ihnen eine Zeichenfolge, die Sie nicht besitzen. Sie dürfen es nicht freigeben oder freigeben.

Ihre ursprüngliche, leere Zeichenfolge leckt übrigens. Sie könnten nur verwenden:

NSString *details = @""; 

details = [details stringByAppendingString:url]; 
details = [details stringByAppendingString:@" : "]; 
details = [details stringByAppendingString:author]; 

return details. 

oder

NSString details = [NSString stringWithFormat: @"%@ : %@", url, author]; 
return details; 
1

Zu allererst Sie Aufteilung und NSString Objekt initialisiert wird und diese Adresse überschreiben später (mem-Leck).

Später durch den Aufruf von StringByAppendingString erhalten Sie bereits "Autoreleased" -Objekt. Explizite Autorelease ist nicht redundant. Es ist doppelte Freisetzung.

1
//This line 

    NSString *details = [[NSString alloc] init]; 
    // In this you are allocating memory for the NSSTring object detail. 

    in the very next lines: 

    details = [details stringByAppendingString:url]; 
    details = [details stringByAppendingString:@" : "]; 
    details = [details stringByAppendingString:author]; 

    // Here you are making same object as autoreleased. That means you have make this instance free to release. 

    Now in next line: 

    return [details autorelease]; 

    // here you are autoreleasing the object which was already autoreleased. So it got crashed. 

, was Sie tun, ist, was @delannoyk Benutzer hat geraten:

{ 
NSMutableString *details = [[NSMutableString alloc] init]; 

    [details appendString:url]; 
    [details appendString:@" : "]; 
    [details appendString:author]; 

    return [details autorelease]; 
}