-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNSObject+AssociatedObject.mm
135 lines (99 loc) · 2.78 KB
/
NSObject+AssociatedObject.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// author: fabrice truillot de chambrier
//
// © 2011-2015, men in silicium sàrl
//
#import "OS/NSObject+AssociatedObject.h"
#import "OS/ARC.h"
#import <objc/runtime.h>
namespace
{
dispatch_once_t _keys_once = 0;
NSMutableDictionary* _keys = nil;
}
@implementation NSObject (AssociatedObject)
+ (void) associatedObjectSetupKeysRegistry
{
dispatch_once( &_keys_once, ^ ()
{
if ( _keys == nil ) _keys = [NSMutableDictionary new];
});
}
+ (const void*) associatedObjectRawKeyForKey: (id) key
{
if ( key == nil ) return nullptr;
NSValue* value = (NSValue*) _keys[key];
if ( value == nil )
{
value = [NSValue valueWithPointer: (__arc_yield const void*) key];
_keys[key] = value;
}
return value.pointerValue;
}
+ (id) associatedObjectKeyForRawKey: (const void*) key
{
if ( key == nullptr ) return nil;
NSValue* value = [NSValue valueWithPointer: key];
NSArray* keys = [_keys allKeysForObject: value];
if ( keys.count == 0 ) return nil;
return keys[0];
}
- (id) associatedObjectForKey: (id) key
{
if ( key == nil ) return nil;
const void* rawKey = [NSObject associatedObjectRawKeyForKey: key];
return [self associatedObjectForRawKey: rawKey];
}
- (id) associatedObjectForRawKey: (const void*) key
{
if ( key == nullptr ) return nil;
return objc_getAssociatedObject( self, key );
}
- (void) setAssociatedObject: (id) object forKey: (id) key
{
if ( key == nil ) return;
if ( _keys == nil ) [NSObject associatedObjectSetupKeysRegistry];
const void* rawKey = [NSObject associatedObjectRawKeyForKey: key];
[self setAssociatedObject: object forRawKey: rawKey];
}
- (void) setAssociatedObject: (id) object forRawKey: (const void*) key
{
if ( key == nullptr ) return;
[self setAssociatedObject: object forRawKey: key policy: OBJC_ASSOCIATION_RETAIN_NONATOMIC];
}
- (void) setAssociatedObject: (id) object forKey: (id) key policy: (NSUInteger) policy
{
if ( key == nil ) return;
const void* rawKey = [NSObject associatedObjectRawKeyForKey: key];
[self setAssociatedObject: object forRawKey: rawKey policy: policy];
}
- (void) setAssociatedObject: (id) object forRawKey: (const void*) key policy: (NSUInteger) policy
{
if ( key == nullptr ) return;
if ( object != nil )
{
// set
objc_setAssociatedObject( self, key, object, policy );
}
else
{
// remove
objc_setAssociatedObject( self, key, nil, OBJC_ASSOCIATION_ASSIGN );
}
}
- (void) removeAssociatedObjectForKey: (id) key
{
if ( key == nil ) return;
const void* rawKey = [NSObject associatedObjectRawKeyForKey: key];
[self removeAssociatedObjectForRawKey: rawKey];
}
- (void) removeAssociatedObjectForRawKey: (const void*) key
{
if ( key == nullptr ) return;
objc_setAssociatedObject( self, key, nil, OBJC_ASSOCIATION_ASSIGN );
}
- (void) removeAssociatedObjects
{
objc_removeAssociatedObjects( self );
}
@end