2010-04-26 12 views
6

Dire che ho una classe tableview che elenca 100 oggetti Foo. Ha:Va bene se più oggetti mantengono lo stesso oggetto in Objective-C/Cocoa?

 
@property (nonatomic, retain) NSMutableArray* fooList; 

e riempire con Foos come:

 
self.fooList = [NSMutableArray array]; 
while (something) { 
    Foo* foo = [[Foo alloc] init]; 
    [fooList addObject:foo]; 
    [foo release]; 
} 

Prima domanda: perché il NSMutableArray è contrassegnato come trattenere, ciò significa tutti gli oggetti al suo interno vengono mantenuti troppo? Sto aggiungendo correttamente il foo e rilasciando la copia locale dopo che è stata aggiunta all'array? O mi manca una chiamata di mantenimento?

Poi, se l'utente seleziona una riga specifica nella tabella e voglio visualizzare un dettaglio vista Foo io chiamo:

 
FooView* localView = [[FooView alloc] initWithFoo:[self.fooList objectAtIndex:indexPath.row]]; 
[self.navigationController pushViewController:localView animated:YES]; 
[localView release]; 

Ora la classe FooView ha:

 
@property (nonatomic, retain) Foo* theFoo; 

così ora entrambi la matrice è aggrappata a quel Foo e al FooView. Ma sembra ok? Quando l'utente preme il pulsante indietro dealloc verrà chiamato su FooView e verrà chiamato [theFoo release]. Quindi viene colpito un altro pulsante indietro e dealloc viene chiamato sulla classe tableview e viene chiamato [fooList release].

Si potrebbe obiettare che la classe FooView dovrebbe avere:

 
@property (nonatomic, assign) Foo* theFoo; 

vs. trattenere. Ma a volte la classe FooView viene chiamata con un Foo che non è anche in un array. Quindi volevo assicurarmi che fosse giusto avere due oggetti che si aggrappavano allo stesso altro oggetto.

risposta

4

Come altri dicono, quello che stai facendo è corretto e il codice mi sembra corretto. Ho decine di riferimenti allo stesso oggetto nel mio codice e fintanto che ho bilanciato tutti i ritegni e le versioni, tutto funziona correttamente.

Per aggiungere ulteriori dettagli ...chiedi:

perché NSMutableArray è contrassegnato come retain, ovvero tutti gli oggetti al suo interno vengono conservati anche tu?

Queste sono due cose diverse. Tutte le classi di raccolta (dizionari, matrici, insiemi) mantengono automaticamente le cose che vengono aggiunte a loro e rilasciano i loro oggetti di contenuto quando l'oggetto di raccolta viene deallocato. (In caso di NSMutableArray, l'oggetto contenuto viene rilasciato sia se lo si rimuove individualmente dall'array, sia quando si rilascia l'intero array.)

Questo non ha nulla a che fare con se l'oggetto stesso viene mantenuto o assegnato come proprietà. L'unica cosa da considerare è che se la tua politica per la proprietà dell'oggetto collection non è corretta, potrebbe essere rilasciata prima o poi di quanto pensi e le cose potrebbero andare fuori equilibrio.

Come altri dicono ... leggi il memory management guide e fai pratica. :) Oh, e leggi anche il codice di altre persone da questa prospettiva e cerca di capire come/perché stanno facendo la loro gestione della memoria.

Un'altra piccola cosa ... per ogni proprietà mantenuta, assicurarsi di avere una chiamata di rilascio nel metodo dealloc dell'oggetto.

+0

Typo: "... e rilasciano i relativi oggetti di contenuto quando viene rilasciato l'oggetto di raccolta." Gli oggetti nelle raccolte non vengono rilasciati fino a quando la raccolta non viene * deallocata *. – JeremyP

+0

Grazie, risolto. Anche se si potrebbe sostenere che con "rilasciato" intendevo "l'ultima versione, in base alla quale il conteggio dei ritiri va a zero e ciò fa scattare dealloc": P, ma solo dicendo dealloc è più chiaro in quel contesto. – Jaanus

4

Sì, è ok. Questo è l'intero punto di un sistema di gestione della memoria di conteggio di riferimento.

5

Per rispondere alla domanda principale, sì è possibile più oggetti che conservano un'istanza. Questo è esattamente il punto di riferimento della gestione della memoria conteggiata. Dai un'occhiata al Cocoa Memory Management Programming Guide per maggiori informazioni. Quindi rileggilo. Ha tutte le risposte e sarà il tuo migliore amico.

In sostanza, l'invio di un messaggio -retain indica che il mittente "possiede" il ricevitore, nel senso che il ricevitore non deve essere deallocata fino tutti proprietari hanno rilasciato la loro proprietà. Pertanto, le singole istanze non hanno bisogno di sapere (né dovrebbero preoccuparsene) se esistono altri proprietari. Conserva tutto ciò che ti serve per restare in giro e rilasciarlo quando hai finito. Quando tutti i proprietari di hanno rilasciato la loro proprietà, un'informazione può essere rilasciata.

Su un lato nota,

@property (retain,readwrite) NSMutableArray *myArray; 

dichiara che la classe dichiarando questa proprietà manterrà l'istanza NSMutableArray. NSArray, NSDictionary e NSSet (e le loro sottoclassi modificabili) mantengono sempre il loro contenuto.

Problemi correlati