How does objc_setAssociatedObject work? [duplicate]
Asked Answered
H

1

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?

Heribertoheringer answered 16/7, 2013 at 13:47 Comment(4)
Any reason for not just using the property? I would try to not mess with the runtime without understanding how it works.Polypus
Here is their implementation.Reopen
@H2CO3, the file with the actually interesting code is objc-references.mm: opensource.apple.com/source/objc4/objc4-532/runtime/…Erigeron
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.Simply
L
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.

Lemal answered 16/7, 2013 at 14:27 Comment(1)
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!Heribertoheringer

© 2022 - 2024 — McMap. All rights reserved.