QNMutableArray.m 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. //
  2. // QNMutableArray.m
  3. // QiniuSDK
  4. //
  5. // Created by yangsen on 2021/7/5.
  6. // Copyright © 2021 Qiniu. All rights reserved.
  7. //
  8. #import "QNMutableArray.h"
  9. #define INIT(...) self = super.init; \
  10. if (!self) return nil; \
  11. __VA_ARGS__; \
  12. if (!_arr) return nil; \
  13. _lock = dispatch_semaphore_create(1); \
  14. return self;
  15. #define LOCK(...) dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER); \
  16. __VA_ARGS__; \
  17. dispatch_semaphore_signal(_lock);
  18. @implementation QNMutableArray {
  19. NSMutableArray *_arr; //Subclass a class cluster...
  20. dispatch_semaphore_t _lock;
  21. }
  22. #pragma mark - init
  23. - (instancetype)init {
  24. INIT(_arr = [[NSMutableArray alloc] init]);
  25. }
  26. - (instancetype)initWithCapacity:(NSUInteger)numItems {
  27. INIT(_arr = [[NSMutableArray alloc] initWithCapacity:numItems]);
  28. }
  29. - (instancetype)initWithArray:(NSArray *)array {
  30. INIT(_arr = [[NSMutableArray alloc] initWithArray:array]);
  31. }
  32. - (instancetype)initWithObjects:(const id[])objects count:(NSUInteger)cnt {
  33. INIT(_arr = [[NSMutableArray alloc] initWithObjects:objects count:cnt]);
  34. }
  35. - (instancetype)initWithContentsOfFile:(NSString *)path {
  36. INIT(_arr = [[NSMutableArray alloc] initWithContentsOfFile:path]);
  37. }
  38. - (instancetype)initWithContentsOfURL:(NSURL *)url {
  39. INIT(_arr = [[NSMutableArray alloc] initWithContentsOfURL:url]);
  40. }
  41. #pragma mark - method
  42. - (NSUInteger)count {
  43. LOCK(NSUInteger count = _arr.count); return count;
  44. }
  45. - (id)objectAtIndex:(NSUInteger)index {
  46. LOCK(id obj = [_arr objectAtIndex:index]); return obj;
  47. }
  48. - (NSArray *)arrayByAddingObject:(id)anObject {
  49. LOCK(NSArray * arr = [_arr arrayByAddingObject:anObject]); return arr;
  50. }
  51. - (NSArray *)arrayByAddingObjectsFromArray:(NSArray *)otherArray {
  52. LOCK(NSArray * arr = [_arr arrayByAddingObjectsFromArray:otherArray]); return arr;
  53. }
  54. - (NSString *)componentsJoinedByString:(NSString *)separator {
  55. LOCK(NSString * str = [_arr componentsJoinedByString:separator]); return str;
  56. }
  57. - (BOOL)containsObject:(id)anObject {
  58. LOCK(BOOL c = [_arr containsObject:anObject]); return c;
  59. }
  60. - (NSString *)description {
  61. LOCK(NSString * d = _arr.description); return d;
  62. }
  63. - (NSString *)descriptionWithLocale:(id)locale {
  64. LOCK(NSString * d = [_arr descriptionWithLocale:locale]); return d;
  65. }
  66. - (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level {
  67. LOCK(NSString * d = [_arr descriptionWithLocale:locale indent:level]); return d;
  68. }
  69. - (id)firstObjectCommonWithArray:(NSArray *)otherArray {
  70. LOCK(id o = [_arr firstObjectCommonWithArray:otherArray]); return o;
  71. }
  72. - (void)getObjects:(id __unsafe_unretained[])objects range:(NSRange)range {
  73. LOCK([_arr getObjects:objects range:range]);
  74. }
  75. - (NSUInteger)indexOfObject:(id)anObject {
  76. LOCK(NSUInteger i = [_arr indexOfObject:anObject]); return i;
  77. }
  78. - (NSUInteger)indexOfObject:(id)anObject inRange:(NSRange)range {
  79. LOCK(NSUInteger i = [_arr indexOfObject:anObject inRange:range]); return i;
  80. }
  81. - (NSUInteger)indexOfObjectIdenticalTo:(id)anObject {
  82. LOCK(NSUInteger i = [_arr indexOfObjectIdenticalTo:anObject]); return i;
  83. }
  84. - (NSUInteger)indexOfObjectIdenticalTo:(id)anObject inRange:(NSRange)range {
  85. LOCK(NSUInteger i = [_arr indexOfObjectIdenticalTo:anObject inRange:range]); return i;
  86. }
  87. - (id)firstObject {
  88. LOCK(id o = _arr.firstObject); return o;
  89. }
  90. - (id)lastObject {
  91. LOCK(id o = _arr.lastObject); return o;
  92. }
  93. - (NSEnumerator *)objectEnumerator {
  94. LOCK(NSEnumerator * e = [_arr objectEnumerator]); return e;
  95. }
  96. - (NSEnumerator *)reverseObjectEnumerator {
  97. LOCK(NSEnumerator * e = [_arr reverseObjectEnumerator]); return e;
  98. }
  99. - (NSData *)sortedArrayHint {
  100. LOCK(NSData * d = [_arr sortedArrayHint]); return d;
  101. }
  102. - (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context {
  103. LOCK(NSArray * arr = [_arr sortedArrayUsingFunction:comparator context:context]) return arr;
  104. }
  105. - (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context hint:(NSData *)hint {
  106. LOCK(NSArray * arr = [_arr sortedArrayUsingFunction:comparator context:context hint:hint]); return arr;
  107. }
  108. - (NSArray *)sortedArrayUsingSelector:(SEL)comparator {
  109. LOCK(NSArray * arr = [_arr sortedArrayUsingSelector:comparator]); return arr;
  110. }
  111. - (NSArray *)subarrayWithRange:(NSRange)range {
  112. LOCK(NSArray * arr = [_arr subarrayWithRange:range]) return arr;
  113. }
  114. - (void)makeObjectsPerformSelector:(SEL)aSelector {
  115. LOCK([_arr makeObjectsPerformSelector:aSelector]);
  116. }
  117. - (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)argument {
  118. LOCK([_arr makeObjectsPerformSelector:aSelector withObject:argument]);
  119. }
  120. - (NSArray *)objectsAtIndexes:(NSIndexSet *)indexes {
  121. LOCK(NSArray * arr = [_arr objectsAtIndexes:indexes]); return arr;
  122. }
  123. - (id)objectAtIndexedSubscript:(NSUInteger)idx {
  124. LOCK(id o = [_arr objectAtIndexedSubscript:idx]); return o;
  125. }
  126. - (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block {
  127. LOCK([_arr enumerateObjectsUsingBlock:block]);
  128. }
  129. - (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block {
  130. LOCK([_arr enumerateObjectsWithOptions:opts usingBlock:block]);
  131. }
  132. - (void)enumerateObjectsAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts usingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block {
  133. LOCK([_arr enumerateObjectsAtIndexes:s options:opts usingBlock:block]);
  134. }
  135. - (NSUInteger)indexOfObjectPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate {
  136. LOCK(NSUInteger i = [_arr indexOfObjectPassingTest:predicate]); return i;
  137. }
  138. - (NSUInteger)indexOfObjectWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate {
  139. LOCK(NSUInteger i = [_arr indexOfObjectWithOptions:opts passingTest:predicate]); return i;
  140. }
  141. - (NSUInteger)indexOfObjectAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts passingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate {
  142. LOCK(NSUInteger i = [_arr indexOfObjectAtIndexes:s options:opts passingTest:predicate]); return i;
  143. }
  144. - (NSIndexSet *)indexesOfObjectsPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate {
  145. LOCK(NSIndexSet * i = [_arr indexesOfObjectsPassingTest:predicate]); return i;
  146. }
  147. - (NSIndexSet *)indexesOfObjectsWithOptions:(NSEnumerationOptions)opts passingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate {
  148. LOCK(NSIndexSet * i = [_arr indexesOfObjectsWithOptions:opts passingTest:predicate]); return i;
  149. }
  150. - (NSIndexSet *)indexesOfObjectsAtIndexes:(NSIndexSet *)s options:(NSEnumerationOptions)opts passingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate {
  151. LOCK(NSIndexSet * i = [_arr indexesOfObjectsAtIndexes:s options:opts passingTest:predicate]); return i;
  152. }
  153. - (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr {
  154. LOCK(NSArray * a = [_arr sortedArrayUsingComparator:cmptr]); return a;
  155. }
  156. - (NSArray *)sortedArrayWithOptions:(NSSortOptions)opts usingComparator:(NSComparator)cmptr {
  157. LOCK(NSArray * a = [_arr sortedArrayWithOptions:opts usingComparator:cmptr]); return a;
  158. }
  159. - (NSUInteger)indexOfObject:(id)obj inSortedRange:(NSRange)r options:(NSBinarySearchingOptions)opts usingComparator:(NSComparator)cmp {
  160. LOCK(NSUInteger i = [_arr indexOfObject:obj inSortedRange:r options:opts usingComparator:cmp]); return i;
  161. }
  162. #pragma mark - mutable
  163. - (void)addObject:(id)anObject {
  164. LOCK([_arr addObject:anObject]);
  165. }
  166. - (void)insertObject:(id)anObject atIndex:(NSUInteger)index {
  167. LOCK([_arr insertObject:anObject atIndex:index]);
  168. }
  169. - (void)removeLastObject {
  170. LOCK([_arr removeLastObject]);
  171. }
  172. - (void)removeObjectAtIndex:(NSUInteger)index {
  173. LOCK([_arr removeObjectAtIndex:index]);
  174. }
  175. - (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject {
  176. LOCK([_arr replaceObjectAtIndex:index withObject:anObject]);
  177. }
  178. - (void)addObjectsFromArray:(NSArray *)otherArray {
  179. LOCK([_arr addObjectsFromArray:otherArray]);
  180. }
  181. - (void)exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2 {
  182. LOCK([_arr exchangeObjectAtIndex:idx1 withObjectAtIndex:idx2]);
  183. }
  184. - (void)removeAllObjects {
  185. LOCK([_arr removeAllObjects]);
  186. }
  187. - (void)removeObject:(id)anObject inRange:(NSRange)range {
  188. LOCK([_arr removeObject:anObject inRange:range]);
  189. }
  190. - (void)removeObject:(id)anObject {
  191. LOCK([_arr removeObject:anObject]);
  192. }
  193. - (void)removeObjectIdenticalTo:(id)anObject inRange:(NSRange)range {
  194. LOCK([_arr removeObjectIdenticalTo:anObject inRange:range]);
  195. }
  196. - (void)removeObjectIdenticalTo:(id)anObject {
  197. LOCK([_arr removeObjectIdenticalTo:anObject]);
  198. }
  199. - (void)removeObjectsInArray:(NSArray *)otherArray {
  200. LOCK([_arr removeObjectsInArray:otherArray]);
  201. }
  202. - (void)removeObjectsInRange:(NSRange)range {
  203. LOCK([_arr removeObjectsInRange:range]);
  204. }
  205. - (void)replaceObjectsInRange:(NSRange)range withObjectsFromArray:(NSArray *)otherArray range:(NSRange)otherRange {
  206. LOCK([_arr replaceObjectsInRange:range withObjectsFromArray:otherArray range:otherRange]);
  207. }
  208. - (void)replaceObjectsInRange:(NSRange)range withObjectsFromArray:(NSArray *)otherArray {
  209. LOCK([_arr replaceObjectsInRange:range withObjectsFromArray:otherArray]);
  210. }
  211. - (void)setArray:(NSArray *)otherArray {
  212. LOCK([_arr setArray:otherArray]);
  213. }
  214. - (void)sortUsingFunction:(NSInteger (*)(id, id, void *))compare context:(void *)context {
  215. LOCK([_arr sortUsingFunction:compare context:context]);
  216. }
  217. - (void)sortUsingSelector:(SEL)comparator {
  218. LOCK([_arr sortUsingSelector:comparator]);
  219. }
  220. - (void)insertObjects:(NSArray *)objects atIndexes:(NSIndexSet *)indexes {
  221. LOCK([_arr insertObjects:objects atIndexes:indexes]);
  222. }
  223. - (void)removeObjectsAtIndexes:(NSIndexSet *)indexes {
  224. LOCK([_arr removeObjectsAtIndexes:indexes]);
  225. }
  226. - (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withObjects:(NSArray *)objects {
  227. LOCK([_arr replaceObjectsAtIndexes:indexes withObjects:objects]);
  228. }
  229. - (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx {
  230. LOCK([_arr setObject:obj atIndexedSubscript:idx]);
  231. }
  232. - (void)sortUsingComparator:(NSComparator)cmptr {
  233. LOCK([_arr sortUsingComparator:cmptr]);
  234. }
  235. - (void)sortWithOptions:(NSSortOptions)opts usingComparator:(NSComparator)cmptr {
  236. LOCK([_arr sortWithOptions:opts usingComparator:cmptr]);
  237. }
  238. - (BOOL)isEqualToArray:(NSArray *)otherArray {
  239. if (otherArray == self) return YES;
  240. if ([otherArray isKindOfClass:QNMutableArray.class]) {
  241. QNMutableArray *other = (id)otherArray;
  242. BOOL isEqual;
  243. dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
  244. dispatch_semaphore_wait(other->_lock, DISPATCH_TIME_FOREVER);
  245. isEqual = [_arr isEqualToArray:other->_arr];
  246. dispatch_semaphore_signal(other->_lock);
  247. dispatch_semaphore_signal(_lock);
  248. return isEqual;
  249. }
  250. return NO;
  251. }
  252. #pragma mark - protocol
  253. - (id)copyWithZone:(NSZone *)zone {
  254. return [self mutableCopyWithZone:zone];
  255. }
  256. - (id)mutableCopyWithZone:(NSZone *)zone {
  257. LOCK(id copiedDictionary = [[self.class allocWithZone:zone] initWithArray:_arr]);
  258. return copiedDictionary;
  259. }
  260. - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
  261. objects:(id __unsafe_unretained[])stackbuf
  262. count:(NSUInteger)len {
  263. LOCK(NSUInteger count = [_arr countByEnumeratingWithState:state objects:stackbuf count:len]);
  264. return count;
  265. }
  266. - (BOOL)isEqual:(id)object {
  267. if (object == self) return YES;
  268. if ([object isKindOfClass:QNMutableArray.class]) {
  269. QNMutableArray *other = object;
  270. BOOL isEqual;
  271. dispatch_semaphore_wait(_lock, DISPATCH_TIME_FOREVER);
  272. dispatch_semaphore_wait(other->_lock, DISPATCH_TIME_FOREVER);
  273. isEqual = [_arr isEqual:other->_arr];
  274. dispatch_semaphore_signal(other->_lock);
  275. dispatch_semaphore_signal(_lock);
  276. return isEqual;
  277. }
  278. return NO;
  279. }
  280. - (NSUInteger)hash {
  281. LOCK(NSUInteger hash = [_arr hash]);
  282. return hash;
  283. }
  284. @end