-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathNSArray+WeakArray.m
120 lines (95 loc) · 2.42 KB
/
NSArray+WeakArray.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
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
//
// NSMutableArray+WeakArray.m
//
#import "NSArray+WeakArray.h"
///
/// A wrapper for a weak pointer, meant to allow for arrays of weak references (that don't suck)
///
@interface WAArrayWeakPointer : NSObject
@property (nonatomic, weak) NSObject *object;
@end
@implementation WAArrayWeakPointer
@end
@implementation NSArray (WeakArray)
///
/// Returns the weakly referenced object at the given index
///
-(__weak id)weakObjectForIndex:(NSUInteger)index
{
WAArrayWeakPointer *ptr = [self objectAtIndex:index];
return ptr.object;
}
///
/// Gets the weak pointer for the given object reference
///
-(WAArrayWeakPointer *)weakPointerForObject:(id)object
{
// Linear search for the object in question
for (WAArrayWeakPointer *ptr in self) {
if(ptr) {
if(ptr.object == object) {
return ptr;
}
}
}
return nil;
}
///
/// Returns a fast enumeration collection for all of the weakly referenced objects in this collection
///
-(id<NSFastEnumeration>)weakObjectsEnumerator
{
NSMutableArray *enumerator = [[NSMutableArray alloc] init];
for (WAArrayWeakPointer *ptr in self) {
if(ptr && ptr.object) {
[enumerator addObject:ptr.object];
}
}
return enumerator;
}
@end
@implementation NSMutableArray (FRSWeakArray)
///
/// Adds a weak reference to the given object to the collection
///
-(void)addWeakObject:(id)object
{
if(!object)
return;
WAArrayWeakPointer *ptr = [[WAArrayWeakPointer alloc] init];
ptr.object = object;
[self addObject:ptr];
[self cleanWeakObjects];
}
///
/// Removes a weakly referenced object from the collection
///
-(void)removeWeakObject:(id)object
{
if(!object)
return;
// Find the underlying object in the array
WAArrayWeakPointer *ptr = [self weakPointerForObject:object];
if(ptr) {
[self removeObject:ptr];
[self cleanWeakObjects];
}
}
///
/// Cleans the collection of any lost weak objects
///
-(void)cleanWeakObjects
{
// Build a list of dead references
NSMutableArray *toBeRemoved = [[NSMutableArray alloc] init];
for (WAArrayWeakPointer *ptr in self) {
if(ptr && !ptr.object) {
[toBeRemoved addObject:ptr];
}
}
// Remove the dead references from the collection
for(WAArrayWeakPointer *ptr in toBeRemoved) {
[self removeObject:ptr];
}
}
@end