Domanda

Ho la seguente classe di esempio:

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;
}

Che produce il seguente output:

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

Lo sto chiamando come:

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

Il valore non dovrebbe avere un conteggio di mantenimento di 1? Cosa mi sto perdendo?

Grazie per il tuo aiuto.

È stato utile?

Soluzione 5

Hai un riferimento a una stringa immutabile. L'assegnazione non deve copiare il valore (i dati della stringa) poiché è immutabile. Se esegui un'operazione mutabile, come value = [newValue uppercaseString], dovrebbe copiare i bit in valore e il conteggio dei valori incrementato aumenta.

Altri suggerimenti

Non guardare i conteggi. Non sono utili e ti fuorviano solo & # 8212; non puoi essere certo che nient'altro trattiene un oggetto, che un oggetto che ottieni da qualche parte non è condiviso.

Invece, concentrati sulla proprietà dell'oggetto e segui Regole di gestione della memoria del cacao alla lettera. In questo modo la gestione della memoria sarà corretta, indipendentemente dalle ottimizzazioni che Cocoa potrebbe fare dietro le quinte per te. (Ad esempio, implementando -copy solo come -retain per oggetti immutabili.)

Inoltre, è fondamentale comprendere la differenza tra proprietà dei tuoi oggetti e variabili di istanza all'interno dei tuoi oggetti. Nel codice della tua domanda, stai assegnando un valore a una variabile di istanza. Quella variabile di istanza è proprio questa: una variabile. L'assegnazione ad esso si comporterà come qualsiasi altra assegnazione di variabili. Per utilizzare la proprietà, è necessario utilizzare la sintassi punto o la sintassi parentesi per richiamare effettivamente il metodo setter della proprietà:

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

Il codice generato per la sintassi del punto e la sintassi della parentesi è identico e nessuno dei due accederà direttamente alla variabile di istanza.

Stai passando una stringa letterale. Il compilatore probabilmente lo alloca nella memoria statica e imposta il conteggio di mantenimento sul valore massimo possibile.

Prova invece una stringa allocata dinamicamente e guarda cosa succede.

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

Stai passando una costante di stringa, che non può davvero essere deallocata. Penso che 2147483647 sia probabilmente UINT_MAX, il che significa sostanzialmente che l'oggetto non può essere rilasciato.

Penso che tu voglia farlo:

self.value = newValue;

che invocherà il setter proprietà e causerà la copia. " value = newValue " assegna semplicemente un valore di puntatore alla variabile di istanza.

Non dovresti prestare attenzione ai conteggi di conservazione, basta seguire le regole di gestione della memoria di Cocoa. http://iamleeg.blogspot.com/2008/12/cocoa- memory-management.html

hmm .. ci stiamo avvicinando.

sembra che il conteggio delle trattenute di newValue sia anche 2147483647.

Ho provato ad allocare dinamicamente la stringa invece con gli stessi risultati del conteggio di mantenimento.

Ho trovato un articolo utile qui: http://www.cocoadev.com/index. pl? NSString

FTA:

NSString restituito da @ " " deve essere rilasciato o è rilasciato automaticamente? Né. @ " " -strings sono della classe NSConstantString ?, e quindi agiscono come atomi in lisp; rimangono in giro. Cioè, se usi @ " cow " in due punti separati nel codice, faranno riferimento allo stesso oggetto. Non credo che -release o -autorelease facciano nulla a nessuno dei due.

Se ho " copia " sulla proprietà, tuttavia, non dovrebbe copiare il contenuto della memoria di destinazione in una nuova memoria con un conteggio di mantenimento di 1? Sembra che l'attributo copy non faccia nulla in questo caso?

#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;
}

Se si esegue il codice sopra, verrà visualizzato un conteggio di conservazione di 1

In Cocoa, molti oggetti immutabili si manterranno semplicemente quando ne chiedi una copia all'interno della stessa zona. Se si garantisce che l'oggetto non cambi (ovvero la sua immutabilità), allora un duplicato esatto è ridondante.

In Objective-C, la classe di stringhe costanti è separata dalla classe NSString di Cocoa, anche se potrebbe essere una sottoclasse di NSString (non ne sono troppo sicura). Questa costante classe di stringhe può sovrascrivere i metodi di NSObject come retain , release e dealloc in modo che non facciano nulla, e sovrascrive anche retainCount in modo che restituisca sempre lo stesso numero, UINT_MAX o giù di lì. Questo perché una stringa costante Objective-C viene creata nella memoria statica. Deve avere il comportamento generale generale di un oggetto Cocoa (quando si utilizza Cocoa) in modo che possa essere aggiunto ad array, usato come chiave di un dizionario ecc., Tranne per quanto riguarda la sua gestione della memoria, poiché è stato allocato in modo diverso.

Dichiarazione di non responsabilità: in realtà non so di cosa sto parlando.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top