8

As we know, we can add a variable in Objective-C using a category and runtime methods like objc_setAssociatedObject and objc_getAssociatedObject. For example:

#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

But does anybody know what does objc_getAssociatedObject or objc_setAssociatedObject do? I mean, where are the variable we add to the object(here is self) stored? And the relationship between variable and self?

Jano
  • 62,815
  • 21
  • 164
  • 192
foogry
  • 835
  • 7
  • 17
  • 1
    Any reason for not just using the property? I would try to not mess with the runtime without understanding how it works. – David Rönnqvist Jul 16 '13 at 13:51
  • 3
    [Here is](http://www.opensource.apple.com/source/objc4/objc4-532/runtime/objc-runtime.mm) their implementation. –  Jul 16 '13 at 13:53
  • 1
    @H2CO3, the file with the actually interesting code is objc-references.mm: http://www.opensource.apple.com/source/objc4/objc4-532/runtime/objc-references.mm – Rob Napier Jul 16 '13 at 14:13
  • Note that tacking data onto objects using associated objects should generally only be used as a tool of last resort. Using it as a part of your design pattern is indicative of a bad design. – bbum Jul 16 '13 at 15:52

1 Answers1

10

The code for associated objects is in objc-references.mm in the Objective-C runtime.

If I understand it correctly, there is one global hash map (static AssociationsHashMap *_map in class AssociationsManager) that maps the address of an object ("disguised" as uintptr_t) to an ObjectAssociationMap.

ObjectAssociationMap stores all associations for one particular object and is created when

void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy)

is called the first time for an object.

ObjectAssociationMap is a hash map that maps the key to value and policy.

When an object is deallocated, _object_remove_assocations() removes all associations and releases the values if necessary.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • You are right,there is a global hash map owned by runtime, and all associated objects are stored by the map.Thank you very much! – foogry Jul 16 '13 at 15:08