2011-11-06 14 views
5

Sto cercando di imparare l'obiettivo C e una delle cose che trovo molto strano da seguire è quando utilizzare alloc e quando no. Prendete per esempio questo snip di codice:Obiettivo C quando utilizzare alloc e quando non su

NSURL *url =[NSURL URLWithString:@"http://www.apple.com"]; 

Perché non c'è bisogno di fare qualcosa di simile ad alloc prima?

UIAlert *alert = [[UIAlertView alloc]] 

Sono sicuro che ci sia solo una cosa di base in Objective C mi manca, ma stranamente sto avendo un momento difficile trovare una spiegazione, senza distacco. Grazie!!

+0

@jrturton: come ho detto, sì ho e non ha molto senso per me, di solito ottengo buone spiegazioni qui, quindi ho pensato che qualcuno potesse dare una buona risposta. La documentazione degli sviluppatori Apple è orribile e si sa che è orribile. Si prega di dare risposte reali alle domande quando si risponde alle mie cose. lo apprezzerei. – gcoleman0828

+0

In nessuna parte della tua domanda dici qualcosa riguardo alla lettura della documentazione o delle parti con cui hai problemi. Non essere così difensivo! – jrturton

risposta

6

Il problema con +alloc è che mantiene il suo risultato, motivo per cui deve essere bilanciato con una chiamata a -release o -autorelease in seguito. Per evitare di digitare ogni volta che viene utilizzata una classe, i progettisti di API creano comunemente il cosiddetto convenienza costruttore o metodo di convenienza. +URLWithString: è uno di loro, ed internamente sembra che questo:

+ (id)URLWithString: (NSString *)str { 
    return [[[self alloc] initWithString: str] autorelease]; 
} 

Così +alloc è sempre chiamato per voi, e così è -autorelease.

Sfondo

Ci sono due grandi tipi di metodi in Objective-C: metodi di classe e metodi di istanza. I metodi di classe vengono inviati a una classe e non richiedono la creazione di un'istanza di tale classe. I metodi di istanza vengono inviati a un'istanza e possono accedere alla memoria occupata dall'istanza. I metodi di classe iniziano con +; metodi di istanza con -.

+alloc è un metodo di classe. Non è magico con particolari poteri di creazione di oggetti. Tutto ciò che fa internamente è qualcosa di simile:

+ (id)alloc { 
    id result = malloc(class_getInstanceSize(self)); 
    if (result) { 
     memset(result, 0, class_getInstanceSize(self)); 
     result->isa = self; 
     result->retainCount = 1; 
    } 
    return result; 
} 

(In realtà è un po 'più complicato di così, ma dovrebbe essere sufficiente qui.) Nota che +alloc è definito come parte di NSObject, non parte di tutti gli oggetti. La gestione della memoria del cacao, con +alloc, -init, -retain, -release, ecc. Non è sempre parte di Objective-C e si possono creare oggetti che non la usano.

È possibile creare istanze di una classe senza chiamare +alloc se si conoscono i giusti incantesimi. Non lo raccomanderei.

+0

Grazie per la risposta dettagliata. Ciò getta un po 'più di luce su ciò di cui ero confuso. Grazie ancora! – gcoleman0828

2

Utilizzare il metodo di allocazione per creare un nuovo oggetto, di proprietà dell'utente. Voglio dire la creazione in questo modo

NSURL *url =[[NSURL allo]initWithString:@"http://www.apple.com"], diventare proprietario di questo oggetto. Dopo l'uso, consente di dire

NSLog ("Url path is %@",url); 

è necessario rilasciare l'oggetto (url)

[url release]; 

Questo è uno dei principale argomento su managment della memoria in Objective C

E la tua statment,

NSURL *url =[NSURL URLWithString:@"http://www.apple.com"];

devo dire che sistema restituirà un URL con una stringa, ma che non è PROPRIO DA TE, quindi non è necessario rilasciarlo, perché il sistema lo rilascerà automaticamente (a questo oggetto automaticamente viene inviato il messaggio di autorelease)

+1

@devcode, ok ha senso, ma credo che la mia prossima domanda sarebbe, perché mai importare se si "Own it" Perché non sempre non utilizzare alloc e quindi non preoccuparti mai di rilasciarlo? Cosa ti compra? – gcoleman0828

+0

Perché con l'oggetto che possiedi, puoi controllare la memoria utilizzata dalla tua app. Sapete che dopo aver usato questo oggetto, dovreste rilasciarlo, usando il conveniente costruttore (come avete fatto), il sistema non rilascia immediatamente quell'oggetto, quindi la vostra app conserva ancora un blocco di memoria non necessaria. L'utilizzo di alloc è la scelta migliore di norma –

Problemi correlati