forked from csaftoiu/ios-queue-object
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNSMutableArray+QueueAdditions.m
128 lines (97 loc) · 3.47 KB
/
NSMutableArray+QueueAdditions.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
121
122
123
124
125
126
127
128
#import "NSMutableArray+QueueAdditions.h"
// Nader Rahimizad, Added Thread safety for inset and remove operations
static char const * const serialQueueKey = "serialQueueKey";
// http://stackoverflow.com/questions/12098011/objective-c-is-nsmutablearray-thread-safe
// http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/
@implementation NSMutableArray (QueueAdditions)
@dynamic objectTag;
- (id)serialQueue {
return objc_getAssociatedObject(self, serialQueueKey);
}
- (void)setSerialQueue:(id)newObjectTag {
objc_setAssociatedObject(self, serialQueueKey, newObjectTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (id)objectAtIndex:(NSUInteger)index {
__block id obj;
if(self.serialQueue == nil)
self.serialQueue = dispatch_queue_create("com.NSMutableArrayQueueAdditions.SerialQueue", NULL);
dispatch_barrier_async(self.serialQueue, ^{
obj = [self.searchResult objectAtIndex:index];
});
return obj;
}
- (void)removeObjectAtIndex:(NSUInteger)index {
if(self.serialQueue == nil)
self.serialQueue = dispatch_queue_create("com.NSMutableArrayQueueAdditions.SerialQueue", NULL);
dispatch_barrier_async(self.serialQueue, ^{
[self.searchResult removeObjectAtIndex:index];
});
}
- (void)insertObject:(id)obj atIndex:(NSUInteger)index {
if(self.serialQueue == nil)
self.serialQueue = dispatch_queue_create("com.NSMutableArrayQueueAdditions.SerialQueue", NULL);
dispatch_barrier_async(self.serialQueue, ^{
[self.searchResult insertObject:obj atIndex:index];
});
}
- (void)appendObject:(id)obj{
if(self.serialQueue == nil)
self.serialQueue = dispatch_queue_create("com.NSMutableArrayQueueAdditions.SerialQueue", NULL);
dispatch_barrier_async(self.serialQueue, ^{
[self.searchResult addObject:obj];
});
}
// Add to the tail of the queue
-(void) enqueue: (id) anObject {
concurrent_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// Push the item in
[self addObject: anObject];
}
// Grab the next item in the queue, if there is one
-(id) dequeue {
// Set aside a reference to the object to pass back
id queueObject = nil;
// Do we have any items?
if ([self lastObject]) {
// Pick out the first one
#if !__has_feature(objc_arc)
queueObject = [[[self objectAtIndex: 0] retain] autorelease];
#else
queueObject = [self objectAtIndex: 0];
#endif
// Remove it from the queue
[self removeObjectAtIndex: 0];
}
// Pass back the dequeued object, if any
return queueObject;
}
// Takes a look at an object at a given location
-(id) peek: (int) index {
// Set aside a reference to the peeked at object
id peekObject = nil;
// Do we have any items at all?
if ([self lastObject]) {
// Is this within range?
if (index < [self count]) {
// Get the object at this index
peekObject = [self objectAtIndex: index];
}
}
// Pass back the peeked at object, if any
return peekObject;
}
// Let's take a look at the next item to be dequeued
-(id) peekHead {
// Peek at the next item
return [self peek: 0];
}
// Let's take a look at the last item to have been added to the queue
-(id) peekTail {
// Pick out the last item
return [self lastObject];
}
// Checks if the queue is empty
-(BOOL) empty {
return ([self lastObject] == nil);
}
@end