完全來自於 iOS 多線程安全與可變字典 的學習
基本相同,舉一反三
直接上樣例代碼
是我參照網上,根據當前業務需求改的。
其實好多人在這里喜歡用類別處理。我個人覺得用類別 極其容易和普通方法混淆,所以為了降低耦合度,增強代碼理解性和可讀性。這里單獨創建類挺好的。用時候使用這個自定義的安全數組就好了。
// MensesTracker // // Created by HF on 2018/6/7. // Copyright © 2018年 huofar. All rights reserved. // #import <Foundation/Foundation.h> @interface SyncMutableArray : NSObject //只讀 - (NSMutableArray *)safeArray; //判斷是否包含對象 - (BOOL)containsObject:(id)anObject; //集合元素數量 - (NSUInteger)count; //獲取元素 - (id)objectAtIndex:(NSUInteger)index; //枚舉元素 - (NSEnumerator *)objectEnumerator; //插入 - (void)insertObject:(id)anObject atIndex:(NSUInteger)index; //插入 - (void)addObject:(id)anObject; //移除 - (void)removeObjectAtIndex:(NSUInteger)index; //移除 - (void)removeObject:(id)anObject; //移除 - (void)removeLastObject; //替換 - (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject; //獲取索引 - (NSUInteger)indexOfObject:(id)anObject; @end
// // SyncMutableArray.m // MensesTracker // // Created by HF on 2018/6/7. // Copyright © 2018年 huofar. All rights reserved. // #import "SyncMutableArray.h" @interface SyncMutableArray () @property (nonatomic, strong) dispatch_queue_t syncQueue; @property (nonatomic, strong) NSMutableArray* array; @end @implementation SyncMutableArray #pragma mark - init 方法 - (instancetype)initCommon { self = [super init]; if (self) { //%p 以16進制的形式輸出內存地址,附加前綴0x NSString* uuid = [NSString stringWithFormat:@"com.huofar.array_%p", self]; //注意:_syncQueue是並行隊列 _syncQueue = dispatch_queue_create([uuid UTF8String], DISPATCH_QUEUE_CONCURRENT); } return self; } - (instancetype)init { self = [self initCommon]; if (self) { _array = [NSMutableArray array]; } return self; } //其他init方法略 #pragma mark - 數據操作方法 (凡涉及更改數組中元素的操作,使用異步派發+柵欄塊;讀取數據使用 同步派發+並行隊列) - (NSMutableArray *)safeArray { __block NSMutableArray *safeArray; dispatch_sync(_syncQueue, ^{ safeArray = _array; }); return safeArray; } - (BOOL)containsObject:(id)anObject { __block BOOL isExist = NO; dispatch_sync(_syncQueue, ^{ isExist = [_array containsObject:anObject]; }); return isExist; } - (NSUInteger)count { __block NSUInteger count; dispatch_sync(_syncQueue, ^{ count = _array.count; }); return count; } - (id)objectAtIndex:(NSUInteger)index { __block id obj; dispatch_sync(_syncQueue, ^{ if (index < [_array count]) { obj = _array[index]; } }); return obj; } - (NSEnumerator *)objectEnumerator { __block NSEnumerator *enu; dispatch_sync(_syncQueue, ^{ enu = [_array objectEnumerator]; }); return enu; } - (void)insertObject:(id)anObject atIndex:(NSUInteger)index { dispatch_barrier_async(_syncQueue, ^{ if (anObject && index < [_array count]) { [_array insertObject:anObject atIndex:index]; } }); } - (void)addObject:(id)anObject { dispatch_barrier_async(_syncQueue, ^{ if(anObject){ [_array addObject:anObject]; } }); } - (void)removeObjectAtIndex:(NSUInteger)index { dispatch_barrier_async(_syncQueue, ^{ if (index < [_array count]) { [_array removeObjectAtIndex:index]; } }); } - (void)removeObject:(id)anObject { dispatch_barrier_async(_syncQueue, ^{ [_array removeObject:anObject];//外邊自己判斷合法性 }); } - (void)removeLastObject { dispatch_barrier_async(_syncQueue, ^{ [_array removeLastObject]; }); } - (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject { dispatch_barrier_async(_syncQueue, ^{ if (anObject && index < [_array count]) { [_array replaceObjectAtIndex:index withObject:anObject]; } }); } - (NSUInteger)indexOfObject:(id)anObject { __block NSUInteger index = NSNotFound; dispatch_sync(_syncQueue, ^{ for (int i = 0; i < [_array count]; i ++) { if ([_array objectAtIndex:i] == anObject) { index = i; break; } } }); return index; } - (void)dealloc { if (_syncQueue) { _syncQueue = NULL; } } @end
參考
1. https://www.aliyun.com/jiaocheng/354967.html
2.https://blog.csdn.net/zhang522802884/article/details/76728902