/
AssociatedObject.m
61 lines (53 loc) · 1.46 KB
/
AssociatedObject.m
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
#include "Test.h"
#include <stdio.h>
#include <inttypes.h>
BOOL deallocCalled = NO;
static const char* objc_setAssociatedObjectKey = "objc_setAssociatedObjectKey";
@interface Associated : Test
@end
@implementation Associated
-(void) dealloc
{
deallocCalled = YES;
[super dealloc];
}
@end
int main(void)
{
@autoreleasepool {
Associated *object = [Associated new];
Test *holder = [[Test new] autorelease];
objc_setAssociatedObject(holder, &objc_setAssociatedObjectKey, object, OBJC_ASSOCIATION_RETAIN);
[object release];
assert(!deallocCalled);
}
// dealloc should be called when holder is released during pool drain
assert(deallocCalled);
deallocCalled = NO;
Associated *object = [Associated new];
Test *holder = [Test new];
objc_setAssociatedObject(holder, &objc_setAssociatedObjectKey, object, OBJC_ASSOCIATION_RETAIN);
[object release]; // commuted into associated object storage
objc_setAssociatedObject(holder, &objc_setAssociatedObjectKey, nil, OBJC_ASSOCIATION_ASSIGN);
[holder release];
assert(deallocCalled);
object = [Associated new];
holder = [Test new];
for (uintptr_t i = 1; i <= 20; ++i)
{
objc_setAssociatedObject(holder, (void*)i, object, OBJC_ASSOCIATION_RETAIN);
}
int lost = 0;
for (uintptr_t i = 1; i <= 20; ++i)
{
if (object != objc_getAssociatedObject(holder, (const void*)i))
{
fprintf(stderr, "lost object %" PRIuPTR "\n", i);
++lost;
}
}
[holder release];
[object release];
assert(0 == lost);
return 0;
}