2013-07-16 14 views
5

Come sappiamo, possiamo aggiungere una variabile in Objective-C usando una categoria e metodi di runtime come objc_setAssociatedObject e objc_getAssociatedObject. Per esempio:Come funziona objc_setAssociatedObject?

#import <objc/runtime.h> 
@interface Person (EmailAddress) 
@property (nonatomic, readwrite, copy) NSString *emailAddress; 
@end 

@implementation Person (EmailAddress) 

static char emailAddressKey; 

- (NSString *)emailAddress { 
    return objc_getAssociatedObject(self, 
            &emailAddressKey); 
} 

- (void)setEmailAddress:(NSString *)emailAddress { 
    objc_setAssociatedObject(self, 
          &emailAddressKey, 
          emailAddress, 
          OBJC_ASSOCIATION_COPY); 
} 
@end 

Ma qualcuno sa quello che fa objc_getAssociatedObject o objc_setAssociatedObject fare? Voglio dire, dove sono memorizzate le variabili che aggiungiamo all'oggetto (qui è self)? E la relazione tra variabile e self?

+1

Qualsiasi motivo per non utilizzare solo la proprietà? Vorrei provare a non scherzare con il runtime senza capire come funziona. –

+3

[Ecco qui] (http://www.opensource.apple.com/source/objc4/objc4-532/runtime/objc-runtime.mm) la loro implementazione. –

+1

@ H2CO3, il file con il codice effettivamente interessante è objc-references.mm: http://www.opensource.apple.com/source/objc4/objc4-532/runtime/objc-references.mm –

risposta

8

Il codice per gli oggetti associati si trova in objc-references.mm nel runtime Objective-C.

Se ho ben capito, c'è una mappa globale di hash (static AssociationsHashMap *_map in class AssociationsManager) che associa l'indirizzo di un oggetto ("travestito" da uintptr_t) ad un ObjectAssociationMap.

ObjectAssociationMap memorizza tutte le associazioni per un particolare oggetto e viene creato quando

si chiama la prima volta per un oggetto.

ObjectAssociationMap è una mappa di hash che mappa lo key in value e policy.

Quando un oggetto è deallocato, _object_remove_assocations() rimuove tutte le associazioni e rilascia i valori se necessario.

+0

Hai ragione, c'è una mappa hash globale di proprietà di runtime e tutti gli oggetti associati sono memorizzati dalla mappa. Grazie mille! – foogry

+0

@wangzz: siete i benvenuti! –