Frage

Ich habe folgende Beispielklasse:

Test.h:

@interface Test : UIButton {
    NSString *value;
}
- (id)initWithValue:(NSString *)newValue;
@property(copy) NSString *value;

Test.m:

@implementation Test
@synthesize value;
- (id)initWithValue:(NSString *)newValue {
    [super init];   
    NSLog(@"before nil value has retain count of %d", [value retainCount]);
    value = nil;
    NSLog(@"on nil value has retain count of %d", [value retainCount]);
    value = newValue;
    NSLog(@"after init value has retain count of %d", [value retainCount]);
    return self;
}

Welche erzeugt die folgende Ausgabe:

2008-12-31 09:31:41.755 Concentration[18604:20b] before nil value has retain count of 0
2008-12-31 09:31:41.756 Concentration[18604:20b] on nil value has retain count of 0
2008-12-31 09:31:41.757 Concentration[18604:20b] after init value has retain count of 2147483647

Ich rufe es mögen:

Test *test = [[Test alloc] initWithValue:@"some text"];

Sollte nicht Wert eine Zählung von 1 behalten hat? Was vermisse ich?

Danke für Ihre Hilfe.

War es hilfreich?

Lösung 5

Sie haben einen Verweis auf eine unveränderliche Zeichenfolge bekommen. Zuordnung muss nicht den Wert (die Zeichenfolgendaten) kopieren, da sie unveränderlich ist. Wenn Sie einen wandelbaren Betrieb, wie Wert do = [newValue uppercaseString] dann sollte es die Bits in Wert kopieren, und den Wert der Beibehaltungszähler erhöht.

Andere Tipps

Sie nicht schauen, zählt behalten. Sie sind nicht sinnvoll und wird nur täuschen Sie - Sie können nicht sicher sein kann, dass nichts anderes ein Objekt zu halten, dass ein Objekt, das Sie von irgendwo bekommen wird nicht geteilt

.

Stattdessen konzentrieren sich auf Objekt Eigentum und folgen Sie den Cocoa Speicher-Management-Regeln auf das Schreiben. Auf diese Weise Ihrer Speicherverwaltung egal richtig sein, was Optimierungen Cocoa kann für Sie hinter den Kulissen tun. (Zum Beispiel der Umsetzung -copy als nur für unveränderliche Objekte -retain.)

Darüber hinaus ist es kritisch , um den Unterschied zwischen Eigenschaften Ihrer Objekte und Instanzvariablen zu verstehen, Ihrer Objekte. In Ihrer Frage des Code zuweisen Sie einen Wert einer Instanzvariablen. Das Instanzvariable ist genau das: eine Variable. Zuweisen es wird wie jede andere Variable Zuordnung verhalten. Um die Eigenschaft zu verwenden, müssen Sie entweder die Punktsyntax oder Klammer-Syntax verwenden, um tatsächlich die Eigenschaft Setter-Methode aufrufen:

self.value = newValue;     // this is exactly equivalent to the next line
[self setValue:newValue];  // this is exactly equivalent to the previous line

Der Code für die Punkt-Syntax und die Klammer-Syntax erzeugt ist identisch, und auch die Instanzvariable direkt zugreifen.

Sie passieren in einer Zeichenkette. Der Compiler wahrscheinlich ordnet sie in statischen Speicher und setzt die Zählung auf den maximal möglichen Wert halten.

Versuchen Sie, einen dynamisch zugewiesenen String statt und sieht, was passiert.

NSString* string = [[NSString alloc] initWithString: @"some text"];
Test* test = [[Test alloc] initWithValue: string];

Sie vorbei in einem String-Konstante, die nicht wirklich aufgehoben werden kann. Ich denke, dass 2147483647 ist wahrscheinlich UINT_MAX, was im Grunde bedeutet, dass das Objekt nicht freigegeben werden kann.

Ich glaube, Sie wollen, dies zu tun:

self.value = newValue;

, die die Eigenschaft Setter aufrufen und bewirken, dass die Kopie auftreten. "Value = newValue" einfach weist einen Zeigerwert auf die Instanzvariable.

Sie sollten ihr Augenmerk nicht auf die Zählungen behalten bezahlen, folgen Sie einfach den Cocoa-Speicher-Management-Regeln. http://iamleeg.blogspot.com/2008/12/cocoa- Speicher-management.html

hmm .. wir immer näher.

es scheint, dass newValue der Beibehaltungszähler ist auch 2147483647.

Ich habe versucht, dynamisch die Zeichenfolge stattdessen mit den gleichen beibehalten Ergebnisse Zahl zugewiesen wird.

fand ich einen hilfreichen Artikel hier: http://www.cocoadev.com/index. pl? NSString

FTA:

Hat kehrt der NSString von @ „“ freigegeben werden muß, oder ist es Autoreleased? Weder. @ „“ - Strings sind die Klasse NSConstantString ?, und so wie Atome in Lisp handeln; sie hängen herum. Das heißt, wenn Sie verwenden @ „Kuh“ in zwei getrennten Stellen im Code, werden sie das gleiche Objekt werden verweisen. Ich glaube nicht, -release oder -autorelease tut nichts, um entweder von ihnen.

allerdings sollte es nicht kopieren Sie den Inhalt des Zielspeichers in neue Speicher mit einem Beibehaltungszähler von 1

Wenn ich „Kopie“ auf dem Grundstück habe? Es scheint, das Kopierattribut tut nichts in diesem Fall?

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    char *cstr = "this is a c string";

    NSString *str = [[NSString alloc] initWithUTF8String:cstr];
    NSLog(@"rc1: %d", [str retainCount]);

    [pool drain];
    return 0;
}

Wenn Sie den obigen Code ausführen, wird es einen Beibehaltungszähler von 1 Anzeige

In Cocoa, werden viele unveränderlichen Objekte einfach selbst behalten, wenn Sie für eine Kopie innerhalb derselben Zone fragen. Wenn das Objekt nicht gewährleistet ist zu ändern (das heißt seine immutableness) dann ein exaktes Duplikat ist überflüssig.

In Objective-C, die konstante String-Klasse ist getrennt zu Cocoa NSString Klasse, obwohl es eine Unterklasse von NSString sein kann (ich bin mir nicht sicher). Diese konstante String-Klasse kann NSObject Methoden wie retain, release und dealloc außer Kraft setzen, so dass sie nichts tun, und auch retainCount außer Kraft setzen, so dass es immer die gleiche Anzahl, UINT_MAX oder so zurückgibt. Dies liegt daran, ein Objective-C konstanter String wird in statischen Speichern erstellt. Es muss das gesamte allgemeine Verhalten eines Cocoa bezweckt (wenn Kakao verwendet wird), so dass es zu Arrays hinzugefügt werden kann, die als Schlüssel zu einem Wörterbuch usw., außer in Bezug auf seine Speicherverwaltung, da es anders zugeordnet wurde.

Disclaimer: Ich weiß nicht wirklich, was ich rede

.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top