2013-03-09 15 views
9

Guardando il codice sorgente della libreria runtime Objective-C, in particolare a objc-runtime-new.mm, ho visto alcune funzioni e anche commenti che si riferivano a classi pigre e non pigre. Sembra che le classi che non hanno un metodo +load sono chiamate classi pigre, ma non ne sono sicuro e probabilmente non è giusto. Dopo aver cercato su Google, non ho trovato nulla sulle classi pigro su Objective-C.Objective-C: che cos'è una classe pigra?

Quindi, qual è una classe pigra in Objective-C? Obj-C ha questa caratteristica? È legato alla presenza di un metodo +load in un'implementazione di classe? Nel file collegato sopra, il sistema di runtime chiama una funzione chiamata _getObjc2NonlazyClassList per ottenere un elenco di classi non pigri da un'immagine. Perché non esiste anche la funzione _getObjc2LazyClassList?

+0

potrebbe essere una classe caricata da un plug-in. forse controlla la documentazione su plugins/dyld/codice caricato dinamicamente – nielsbot

+0

Sei sicuro che significhi che la classe è pigra e non solo la lista? –

+0

Sono d'accordo con @JoshCaswell, dato che più avanti nella fonte di runtime ci sono riferimenti al caricamento lento nelle classi. Quasi certamente si riferisce alla lista, piuttosto che una classe è "pigra". – lxt

risposta

11

Ho trovato la risposta: si tratta di una classe che implementa o meno un metodo +load.

Tutte le classi implementate in un determinato file di immagine hanno un riferimento in un elenco memorizzato nella sezione del binario "__DATA, __objc_classlist, regular, no_dead_strip".Questo elenco consente al sistema runtime di tenere traccia di tutte le classi memorizzate in tale file. Tuttavia, non tutte le classi devono essere realizzate all'avvio del programma. Ecco perché quando una classe implementa un metodo +load, ha anche un riferimento in un elenco memorizzato nella sezione "__DATA, __objc_nlclslist, regular, no_dead_strip".

Quindi, _getObjc2NonlazyClassList recupera l'elenco di classi che implementano un metodo +load e sono così chiamati non-pigri. _getObjc2ClassList recupera un elenco di tutte le classi in un file immagine, incluse le classi che non hanno un metodo +load (e sono chiamati pigri) e non pigri. Le classi non pigre devono essere realizzate all'avvio del programma. Le classi pigre, d'altra parte, non hanno bisogno di essere realizzate immediatamente. Questo può essere ritardato fino a quando la classe riceve un messaggio per la prima volta, ad esempio (questo è il motivo per cui devono essere considerati "pigri").

Lo stesso vale per le categorie, tra l'altro.

+0

Basta notare che per le categorie, devi usare il flag link all_load' se queste categorie sono in una libreria esterna. –

+0

Questo potrebbe essere quasi corretto, ma ho visto immagini MachO che contengono un __objc_nlclslist, ma non contengono una sezione __objc_classlist. – jsears

5

"Pigro" è utilizzato in due diversi contesti.

Il primo, quando criticare un disegno di classe, sostiene che una classe è inefficace - che non fa abbastanza per giustificare la sua esistenza. La gente chiama anche questo tipo di classe "sottile". Questo probabilmente non è quello che intendi qui.

secondo luogo, valutazione pigra e istanziazione pigrizia significa che la classe fa solo il lavoro di valutare una proprietà o inizializzazione stesso quando effettivamente necessario.

Ad esempio, supponiamo di avere una classe che crea un oggetto Impiegato.

@implementation Employee 
- (id) initWithID: (IdentificationCode*) ident 
{ 
    self =[super init] 
    if (self) { 
     _records=[self retrieveEmployeeRecordsFor: ident]; 
     _identification=ident; 
     } 
    return self; 
} 

Questo va bene, ma il recupero di tutti i record da un database potrebbe essere lento. E a volte non abbiamo bisogno di fare il lavoro. Per esempio:

- (BOOL) isFounder 
{ 
    if (indent.number<10) return YES; 
    return NO; 
} 

Se stiamo istanziare un impiegato semplicemente per scoprire se sono un fondatore, non abbiamo bisogno di guardare i loro record a tutti!

..... 
if ([thisEmployee isFounder]) { 
     [self sendCandyTo: thisEmployee.identification]; 
     } 

D'altra parte, a volte abbiamo bisogno di loro:

- (NSArray*) payments 
{ 
    return [self.records retrievePayStubs]; 
    } 

Quindi, se stiamo costruendo un impiegato solo per chiamare isFounder, sprechiamo una ricerca nel database. Ma non possiamo ignorarlo, perché payments ne ha bisogno.

Quello che facciamo è prendere la ricerca del database dal costruttore e inserirla in un metodo load.

- (void) load 
{ 
    if (records) return; 
    self.records=[self retrieveEmployeeRecordsFor: ident]; 
} 

- (NSArray*) payments 
{ 
    [self load]; 
    return [self.records retrievePayStubs]; 
    } 

Ora, vengono caricati solo i record dei dipendenti quando ne abbiamo effettivamente bisogno. Se sono già stati caricati, non eseguiamo alcun lavoro aggiuntivo (a parte una chiamata al metodo). Se non abbiamo mai bisogno dei registri di pagamento, allora non abbiamo affatto bisogno di fare il lavoro.

La classe funziona solo quando è necessario - e attende fino all'ultimo minuto per eseguire il lavoro. È "pigro!"

+0

Grazie per aver risposto, Mark. Questo è quello che ho immaginato. Quindi, una classe è considerata "pigra" a causa del suo comportamento. Ma qualcosa mi infastidisce ancora: l'esistenza della funzione '_getObjc2NonlazyClassList' che sembra caricare le classi che sono memorizzate come non-pigri nel file immagine. È come se ci fosse un aspetto che rende una classe non-pigra al momento della compilazione. O forse è solo nomenclatura: tutte le classi caricate da un file immagine sono considerate non-pigre ... – LuisABOL

Problemi correlati