5

Jak wiemy, możemy dodać zmienną w Objective-C używając metod kategorii i runtime, takich jak objc_setAssociatedObject i objc_getAssociatedObject. Na przykład:Jak działa 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 

Ale czy ktoś wie, co robi objc_getAssociatedObject lub objc_setAssociatedObject zrobić? Mam na myśli, gdzie są przechowywane zmienne, które dodajemy do obiektu (tutaj jest self)? A związek między zmienną a self?

+1

Każdy powód nie tylko korzystania z nieruchomości? Próbowałbym nie zadzierać z runtime bez zrozumienia, jak to działa. –

+3

[Tutaj jest] (http://www.opensource.apple.com/source/objc4/objc4-532/runtime/objc-runtime.mm) ich implementacja. –

+1

@ H2CO3, plik z naprawdę interesującym kodem to objc-references.mm: http://www.opensource.apple.com/source/objc4/objc4-532/runtime/objc-references.mm –

Odpowiedz

8

Kod powiązanych obiektów znajduje się w objc-references.mm w środowisku wykonawczym Objective-C.

Jeśli rozumiem go poprawnie, jest jedna globalna mapa hash (static AssociationsHashMap *_map w class AssociationsManager), który odwzorowuje adres obiektu („zamaskowane” jako uintptr_t) do ObjectAssociationMap.

ObjectAssociationMap przechowuje wszystkie stowarzyszenia dla jednego konkretnego obiektu i jest tworzony gdy

nazywa się po raz pierwszy od obiektu.

ObjectAssociationMap to mapa skrótu, która mapuje key na value i policy.

Gdy obiekt zostaje zwolniony, _object_remove_assocations() usuwa wszystkie asocjacje i w razie potrzeby zwalnia wartości.

+0

Masz rację, istnieje globalna tablica skrótów należąca do środowiska wykonawczego, a wszystkie powiązane obiekty są przechowywane przez mapę. Dziękuję bardzo! – foogry

+0

@wangzz: Nie ma za co! –