Vai al contenuto

Dubbio su NSMutableArray e NSMutableDictionary


Cpu86

Messaggi raccomandati

Nella documentazione di Cocoa dice che quando aggiungo un oggetto a un MutableDictionary o MutableArray (o altra classe che viene inizializzata con(o aggiunto) un oggetto), questo nn viene copiato ma viene mandato il messaggio "retain".

Ora, posso farlo in tre modi:

1:

NSMutableArray *prova;

prova = [[NSMutableArray alloc] initWithCapacity:1];

[prova addObject:[NSString stringWithCString:"ciao"]];

2:

NSMutableArray *prova;

NSString *ciao;

ciao = [[NSString alloc] initWithCString:"ciao"];

prova = [[NSMutableArray alloc] initWithCapacity:1];

[prova addObject:ciao];

[ciao release];

3:

NSMutableArray *prova;

prova = [[NSMutableArray alloc] initWithCapacity:1];

[prova addObject:[[NSString alloc] initWithCString:"ciao"]];

Lo stesso vale per MutableDictionary (e qualsiasi altra classe che viene inizializzata con(o aggiunto)un oggetto).

Quale è la soluzione migliore? Cioè quella in cui non rischio un memory leak?

Io penso sia la seconda, però vorrei sentire il parere di qualcuno che ha più esperienza di me in Cocoa.

Grazie

Link al commento
Condividi su altri siti

Prima di tutto ti faccio un applauso perché è raro trovare qualcuno che si interessi seriamente a Cocoa.

Passo subito a risponderti. Se crei un oggetto (in questo caso l'oggetto prova) con il metodo +alloc / -init devi rilasciarlo tu a manina quando lo ritieni opportuno con il metodo -release. Di conseguenza il primo e il terzo listato che hai scritto sono scorretti perché non includono la funzione release.

Dopo aver dichiarato l'oggetto (con binding statico come fai tu, oppure semplicemente in modo dinamico con id prova; ) devi effettivamente costruire l'oggetto con il metodo +alloc e poi inizializzarlo.

Io farei quindi:

id prova;

prova = [[NSMutableArray alloc] initWithCapacity:1];

//bla bla bla

[prova release];

oppure:

NSMutableArray *prova;

prova = [[NSMutableArray alloc] initWithCapacity:1];

//bla bla bla

[prova release];

Ora, è un bel po' che non uso Cocoa, però c'è una cosuccia molto comoda di Objective-C che dovresti guardare: si chiama -autorelease. Mette cioè gli oggetti in un mucchio a parte quando termina l'evento e, quando l'applicazione è sicura che non gli servirà più, li rilascia in automatico. Non chiedermi come faccia.

La sintassi comunque è questa:

NSMutableArray *prova;

prova = [NSMutableArray arrayWithCapacity:1];

Molto più veloce e semplice, non trovi?

È tutto qui, in pratica non inizializzi... ora non so se sia corretto al 100% ma ho sempre fatto così e non ho mai avuto problemi di memoria nelle mie piccole applicazioni. Se sei interessato allo studio però ti consiglio vivamente di approfondire la sotria dell'autorelease, io non sono mai andato molto d'accordo con le allocazioni di memoria :D

:ciao:

:aereo:

Link al commento
Condividi su altri siti

Dunque:

ho capito quello che vuoi dire, -autorelease lo uso già.

Nel codice che ho postato non c'è il release di prova perchè è uno spezzone

La mia domanda però era diversa, riguardava l'aggiunta di un oggetto, cioè quando ad esempio aggiungo un oggetto a un dictionary o a un mutablearray o setto una mutablestring, oppure quando inizializzo un nsstring. Non so se mi sono spiegato.

Link al commento
Condividi su altri siti

Ma LOL ho capito, parli di mettere l'NSString dentro il MutableDictionary.

Dunque, analizziamo con calma. Nel secondo listato di sicuro non ci sono errori, perché crei l'oggetto ciao, lo butti dentro e poi lo elimini. Funziona di sicuro alla perfezione, ma mi pare troppo dispendioso di linee di codice, vediamo se si può fare in maniera più rapida.

Nel primo listato non ci sono errori di sicuro perché non allochi l'NSString.

Nel terzo listato vai ad allocare una NSString non identificata e non mi spiego come potresti rilasciarla. I casi son due: o come con l'autorelease finito il cliclo viene buttata o rimane lì. Di sicuro non la puoi deallocare a mano. Ma da quello che ho studiato (e ti hod etto prima) OGNI oggetto che viene allocato con +alloc / -init va deallocata a mano se no rimane bloccato fino al termine dell'applicazione.

Per funzionare vanno tutti e tre. Corretti sono i primi due. Io userei il primo sistema, non amo scrivere molto codice (superfluo tra l'altro).

:ciao:

:aereo:

Link al commento
Condividi su altri siti

Ho un altro dubbio.

Quando creo una classe (oppure un oggetto controller per la GUI), siccome nell'+init alloco dello spazio per alcuni oggetti, è meglio implementare il -dealloc o il -release, in cui inviare il -release agli oggetti allocati, per la suddetta classe?

Spero che tu abbia capito quello che voglio dire.

Link al commento
Condividi su altri siti

Veramente non ho capito... fai conto che non stai parlando con un programmatore :D (nella vita faccio tutt'altro) ma con uno che ha nozioni proprio basilari :ciao:

Forse se mi porti qualche esempio posso esserti più di aiuto (o magari passa di qui qualcuno che conosce per davvero Cocoa :ciao: )

:aereo:

Link al commento
Condividi su altri siti

Dunque ti faccio un esempio:

@implementation mia_classe

- (void)init

{

prova = [[NSString alloc] initWithString:@"ciao"]; //alloco lo spazio per l'oggetto prova (dich. in @interface)

[super init];

}

Ora quell'oggetto lo devo deallocare, giusto? La mia domanda è:

lo dealloco facendo un overloading del metodo dealloc, cioè:

- (void)dealloc

{

[prova release];

[super dealloc];

}

oppure del metodo release?:

- (void)release

{

[prova release];

[super release];

}

Spero di essere stato chiaro :ciao:

Ciao.

Link al commento
Condividi su altri siti

Archiviato

Questa discussione è archiviata e chiusa a future risposte.

×
×
  • Crea Nuovo...