123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- // ATSafeThreadDictionary.h
- // ATSDK
- //
- // Created by topon on 2020/9/21.
- // Copyright © 2020 AnyThink. All rights reserved.
- //
- #import "ATUnitySafeThreadDictionary.h"
- #import <pthread.h>
- #define INIT(...) self = super.init; \
- if (!self) return nil; \
- __VA_ARGS__; \
- if (!_dic) return nil; \
- [self __initMutex:&_mutex_lock];\
- return self;
- #define LOCK(...) pthread_mutex_lock(&_mutex_lock); \
- __VA_ARGS__; \
- pthread_mutex_unlock(&_mutex_lock);
- @implementation ATUnitySafeThreadDictionary {
- NSMutableDictionary *_dic; //Subclass a class cluster...
- pthread_mutex_t _mutex_lock;
- pthread_mutexattr_t _attr;
- }
- #pragma mark - init
- - (void)__initMutex:(pthread_mutex_t *)mutex {
- // 递归锁:允许同一个线程对一把锁进行重复加锁
- // 初始化属性
- pthread_mutexattr_init(&_attr);
- pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_RECURSIVE);
- // 初始化锁
- pthread_mutex_init(mutex, &_attr);
- }
- - (instancetype)init {
-
- INIT(_dic = [[NSMutableDictionary alloc] init]);
- }
- - (instancetype)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys {
- INIT(_dic = [[NSMutableDictionary alloc] initWithObjects:objects forKeys:keys]);
- }
- - (instancetype)initWithCapacity:(NSUInteger)capacity {
- INIT(_dic = [[NSMutableDictionary alloc] initWithCapacity:capacity]);
- }
- - (instancetype)initWithObjects:(const id[])objects forKeys:(const id <NSCopying>[])keys count:(NSUInteger)cnt {
- INIT(_dic = [[NSMutableDictionary alloc] initWithObjects:objects forKeys:keys count:cnt]);
- }
- - (instancetype)initWithDictionary:(NSDictionary *)otherDictionary {
- INIT(_dic = [[NSMutableDictionary alloc] initWithDictionary:otherDictionary]);
- }
- - (instancetype)initWithDictionary:(NSDictionary *)otherDictionary copyItems:(BOOL)flag {
- INIT(_dic = [[NSMutableDictionary alloc] initWithDictionary:otherDictionary copyItems:flag]);
- }
- #pragma mark - method
- - (NSUInteger)count {
- LOCK(NSUInteger c = _dic.count); return c;
- }
- - (id)objectForKey:(id)aKey {
- LOCK(id o = [_dic objectForKey:aKey]); return o;
- }
- - (NSEnumerator *)keyEnumerator {
- LOCK(NSEnumerator * e = [_dic keyEnumerator]); return e;
- }
- - (NSArray *)allKeys {
- LOCK(NSArray * a = [_dic allKeys]); return a;
- }
- - (NSArray *)allKeysForObject:(id)anObject {
- LOCK(NSArray * a = [_dic allKeysForObject:anObject]); return a;
- }
- - (NSArray *)allValues {
- LOCK(NSArray * a = [_dic allValues]); return a;
- }
- - (NSString *)description {
- LOCK(NSString * d = [_dic description]); return d;
- }
- - (NSString *)descriptionInStringsFileFormat {
- LOCK(NSString * d = [_dic descriptionInStringsFileFormat]); return d;
- }
- - (NSString *)descriptionWithLocale:(id)locale {
- LOCK(NSString * d = [_dic descriptionWithLocale:locale]); return d;
- }
- - (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level {
- LOCK(NSString * d = [_dic descriptionWithLocale:locale indent:level]); return d;
- }
- - (BOOL)isEqualToDictionary:(NSDictionary *)otherDictionary {
- if (otherDictionary == self) return YES;
-
- if ([otherDictionary isKindOfClass:ATUnitySafeThreadDictionary.class]) {
- ATUnitySafeThreadDictionary *other = (id)otherDictionary;
- BOOL isEqual;
- pthread_mutex_lock(&_mutex_lock);
- pthread_mutex_lock(&(other->_mutex_lock));
- isEqual = [_dic isEqual:other->_dic];
- pthread_mutex_unlock(&_mutex_lock);
- pthread_mutex_unlock(&(other->_mutex_lock));
- return isEqual;
- }
- return NO;
- }
- - (NSEnumerator *)objectEnumerator {
- LOCK(NSEnumerator * e = [_dic objectEnumerator]); return e;
- }
- - (NSArray *)objectsForKeys:(NSArray *)keys notFoundMarker:(id)marker {
- LOCK(NSArray * a = [_dic objectsForKeys:keys notFoundMarker:marker]); return a;
- }
- - (NSArray *)keysSortedByValueUsingSelector:(SEL)comparator {
- LOCK(NSArray * a = [_dic keysSortedByValueUsingSelector:comparator]); return a;
- }
- - (void)getObjects:(id __unsafe_unretained[])objects andKeys:(id __unsafe_unretained[])keys {
- LOCK([_dic getObjects:objects andKeys:keys]);
- }
- - (id)objectForKeyedSubscript:(id)key {
- LOCK(id o = [_dic objectForKeyedSubscript:key]); return o;
- }
- - (void)enumerateKeysAndObjectsUsingBlock:(__attribute__((noescape)) void (^)(id key, id obj, BOOL *stop))block {
- LOCK([_dic enumerateKeysAndObjectsUsingBlock:block]);
- }
- - (void)enumerateKeysAndObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(__attribute__((noescape)) void (^)(id key, id obj, BOOL *stop))block {
- LOCK([_dic enumerateKeysAndObjectsWithOptions:opts usingBlock:block]);
- }
- - (NSArray *)keysSortedByValueUsingComparator:(__attribute__((noescape)) NSComparator)cmptr {
- LOCK(NSArray * a = [_dic keysSortedByValueUsingComparator:cmptr]); return a;
- }
- - (NSArray *)keysSortedByValueWithOptions:(NSSortOptions)opts usingComparator:(__attribute__((noescape)) NSComparator)cmptr {
- LOCK(NSArray * a = [_dic keysSortedByValueWithOptions:opts usingComparator:cmptr]); return a;
- }
- - (NSSet *)keysOfEntriesPassingTest:(__attribute__((noescape)) BOOL (^)(id key, id obj, BOOL *stop))predicate {
- LOCK(NSSet * a = [_dic keysOfEntriesPassingTest:predicate]); return a;
- }
- - (NSSet *)keysOfEntriesWithOptions:(NSEnumerationOptions)opts passingTest:(__attribute__((noescape)) BOOL (^)(id key, id obj, BOOL *stop))predicate {
- LOCK(NSSet * a = [_dic keysOfEntriesWithOptions:opts passingTest:predicate]); return a;
- }
- #pragma mark - mutable
- - (void)removeObjectForKey:(id)aKey {
- LOCK(
- if (aKey) {
- [_dic removeObjectForKey:aKey];
- });
- }
- - (void)setObject:(id)anObject forKey:(id <NSCopying> )aKey {
- LOCK(
- if (anObject && aKey) {
- [_dic setObject:anObject forKey:aKey];
- });
- }
- - (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary {
- LOCK(
- if (otherDictionary) {
- [_dic addEntriesFromDictionary:otherDictionary];
- });
- }
- - (void)removeAllObjects {
- LOCK([_dic removeAllObjects]);
- }
- - (void)removeObjectsForKeys:(NSArray *)keyArray {
- LOCK([_dic removeObjectsForKeys:keyArray]);
- }
- - (void)setDictionary:(NSDictionary *)otherDictionary {
- LOCK(
- if (otherDictionary) {
- [_dic setDictionary:otherDictionary];
- });
- }
- - (void)setObject:(id)obj forKeyedSubscript:(id <NSCopying> )key {
- LOCK(
- if (obj && key) {
- [_dic setObject:obj forKeyedSubscript:key];
- });
- }
- #pragma mark - protocol
- - (id)copyWithZone:(NSZone *)zone {
- return [self mutableCopyWithZone:zone];
- }
- - (id)mutableCopyWithZone:(NSZone *)zone {
- LOCK(id copiedDictionary = [[self.class allocWithZone:zone] initWithDictionary:_dic]);
- return copiedDictionary;
- }
- - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
- objects:(id __unsafe_unretained[])stackbuf
- count:(NSUInteger)len {
- LOCK(NSUInteger count = [_dic countByEnumeratingWithState:state objects:stackbuf count:len]);
- return count;
- }
- - (BOOL)isEqual:(id)object {
- if (object == self) return YES;
-
- if ([object isKindOfClass:ATUnitySafeThreadDictionary.class]) {
- ATUnitySafeThreadDictionary *other = object;
- BOOL isEqual;
- pthread_mutex_lock(&_mutex_lock);
- pthread_mutex_lock(&(other->_mutex_lock));
- isEqual = [_dic isEqual:other->_dic];
- pthread_mutex_unlock(&_mutex_lock);
- pthread_mutex_unlock(&(other->_mutex_lock));
-
- return isEqual;
- }
- return NO;
- }
- - (NSUInteger)hash {
- LOCK(NSUInteger hash = [_dic hash]);
- return hash;
- }
- - (void)dealloc {
- pthread_mutex_destroy(&_mutex_lock);
- pthread_mutexattr_destroy(&_attr);
- }
- @end
|