diff --git a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m index c8b1ecafbc..993e7913f8 100644 --- a/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m +++ b/ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m @@ -30,7 +30,6 @@ #import "WXSDKManager.h" #import "WXDebugTool.h" #import "WXSDKInstance_private.h" -#import "WXThreadSafeMutableArray.h" #import "WXAppConfiguration.h" #import "WXInvocationConfig.h" #import "WXComponentMethod.h" diff --git a/ios/sdk/WeexSDK/Sources/Component/WXListComponent.mm b/ios/sdk/WeexSDK/Sources/Component/WXListComponent.mm index b4cc6c77c7..a9f18bf1b1 100644 --- a/ios/sdk/WeexSDK/Sources/Component/WXListComponent.mm +++ b/ios/sdk/WeexSDK/Sources/Component/WXListComponent.mm @@ -31,7 +31,6 @@ #import "WXSDKInstance_private.h" #import "WXRefreshComponent.h" #import "WXLoadingComponent.h" -#import "WXThreadSafeMutableArray.h" @interface WXTableView : UITableView @@ -95,12 +94,8 @@ @implementation WXSectionComponent - (instancetype)init { if (self = [super init]) { - if ([WXUtility listSectionRowThreadSafe]) { - _rows = [WXThreadSafeMutableArray array]; - } else { - _rows = [NSMutableArray array]; - } } - + _rows = [NSMutableArray array]; + } return self; } diff --git a/ios/sdk/WeexSDK/Sources/Controller/WXRootViewController.m b/ios/sdk/WeexSDK/Sources/Controller/WXRootViewController.m index 84426bb75d..4d0a8b82d2 100644 --- a/ios/sdk/WeexSDK/Sources/Controller/WXRootViewController.m +++ b/ios/sdk/WeexSDK/Sources/Controller/WXRootViewController.m @@ -19,14 +19,13 @@ #import "WXRootViewController.h" #import "WXBaseViewController.h" -#import "WXThreadSafeMutableArray.h" #import "WXDefine.h" typedef void(^OperationBlock)(void); @interface WXRootViewController() -@property(nonatomic, strong) WXThreadSafeMutableArray *operationArray; +@property (nonatomic, strong) NSMutableArray *operationArray; @property (nonatomic, assign) BOOL operationInProcess; @end @@ -131,11 +130,10 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer return YES; } -- (NSMutableArray *)pendingBlocks +- (NSMutableArray *)operationArray { - if (nil == _operationArray) { - _operationArray = [[WXThreadSafeMutableArray alloc] init]; + _operationArray = [[NSMutableArray alloc] init]; } return _operationArray; diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m index 5e076fea2f..a0e8e4e2a2 100644 --- a/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m +++ b/ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m @@ -31,12 +31,13 @@ #import "WXTracingManager.h" #import "WXMonitor.h" #import "WXSDKInstance_performance.h" +#import "WXThreadSafeMutableArray.h" @interface WXBridgeManager () -@property (nonatomic, strong) WXBridgeContext *bridgeCtx; -@property (nonatomic, assign) BOOL stopRunning; -@property (nonatomic, strong) NSMutableArray *instanceIdStack; +@property (nonatomic, assign) BOOL stopRunning; +@property (nonatomic, strong) WXBridgeContext *bridgeCtx; +@property (nonatomic, strong) WXThreadSafeMutableArray *instanceIdStack; @end @@ -202,26 +203,24 @@ - (void)createInstance:(NSString *)instance } -- (NSMutableArray *)instanceIdStack +- (WXThreadSafeMutableArray *)instanceIdStack { if (_instanceIdStack) return _instanceIdStack; - _instanceIdStack = [NSMutableArray array]; + _instanceIdStack = [[WXThreadSafeMutableArray alloc] init]; return _instanceIdStack; } - (NSArray *)getInstanceIdStack; { - return self.instanceIdStack; + return [self.instanceIdStack copy]; } - (void)destroyInstance:(NSString *)instance { if (!instance) return; - if([self.instanceIdStack containsObject:instance]){ - [self.instanceIdStack removeObject:instance]; - } + [self.instanceIdStack removeObject:instance]; __weak typeof(self) weakSelf = self; WXPerformBlockOnBridgeThread(^(){ diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm index d6e462ee8c..e9b1733e7f 100644 --- a/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm +++ b/ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm @@ -89,7 +89,11 @@ - (instancetype)initWithWeexInstance:(id)weexInstance pthread_mutexattr_init(&_propertMutexAttr); pthread_mutexattr_settype(&_propertMutexAttr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&_propertyMutex, &_propertMutexAttr); - [self _startDisplayLink]; + + WXPerformBlockOnComponentThread(^{ + // We should ensure that [WXDisplayLinkManager sharedInstance] is only invoked in component thread. + [self _startDisplayLink]; + }); } return self; diff --git a/ios/sdk/WeexSDK/Sources/Manager/WXSDKManager.m b/ios/sdk/WeexSDK/Sources/Manager/WXSDKManager.m index 797f4b7184..c7d701036b 100644 --- a/ios/sdk/WeexSDK/Sources/Manager/WXSDKManager.m +++ b/ios/sdk/WeexSDK/Sources/Manager/WXSDKManager.m @@ -81,7 +81,7 @@ + (void)removeInstanceforID:(NSString *)identifier + (void)unload { - for (NSString *instanceID in [self sharedInstance].instanceDict) { + for (NSString *instanceID in [[self sharedInstance].instanceDict allKeys]) { WXSDKInstance *instance = [[self sharedInstance].instanceDict objectForKey:instanceID]; [instance destroyInstance]; } diff --git a/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm index a2e43ead7f..95ac4146ec 100644 --- a/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm +++ b/ios/sdk/WeexSDK/Sources/Model/WXComponent.mm @@ -30,8 +30,6 @@ #import "WXConvert.h" #import "WXMonitor.h" #import "WXAssert.h" -#import "WXThreadSafeMutableDictionary.h" -#import "WXThreadSafeMutableArray.h" #import "WXTransform.h" #import "WXRoundedRect.h" #import diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h index 52dee073a7..87e26f9129 100644 --- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h +++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h @@ -82,7 +82,7 @@ extern NSString *const bundleUrlOptionKey; @property (nonatomic, strong) NSDictionary* containerInfo; /** - * Whether this instance is rendered or not. Please MUST not render an instance twice. + * Whether this instance is rendered or not. Please MUST not render an instance twice even if you have called destroyInstance. **/ @property (nonatomic, assign, readonly) BOOL isRendered; @@ -276,7 +276,7 @@ typedef NS_ENUM(NSInteger, WXErrorCode) {//error.code - (void)refreshInstance:(id)data; /** - * Destroys current instance. + * Destroys current instance. An instance destroyed should not be used for rendering again, please create another instance. **/ - (void)destroyInstance; diff --git a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m index ab3c557518..87bc32650b 100644 --- a/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m +++ b/ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m @@ -75,7 +75,6 @@ @implementation WXSDKInstance WXRootView *_rootView; WXThreadSafeMutableDictionary *_moduleEventObservers; BOOL _performanceCommit; - BOOL _syncDestroyComponentManager; BOOL _debugJS; id _instanceJavaScriptContext; // sandbox javaScript context CGFloat _defaultPixelScaleFactor; @@ -87,11 +86,6 @@ - (void)dealloc { [_moduleEventObservers removeAllObjects]; [self removeObservers]; - if (_syncDestroyComponentManager) { - WXPerformBlockSyncOnComponentThread(^{ - _componentManager = nil; - }); - } } - (instancetype)init @@ -123,10 +117,6 @@ - (instancetype)init _performance = [[WXPerformance alloc] init]; _apmInstance = [[WXApmForInstance alloc] init]; - id configCenter = [WXSDKEngine handlerForProtocol:@protocol(WXConfigCenterProtocol)]; - if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) { - _syncDestroyComponentManager = [[configCenter configForKey:@"iOS_weex_ext_config.syncDestroyComponentManager" defaultValue:@(YES) isDefault:NULL] boolValue]; - } _defaultPixelScaleFactor = CGFLOAT_MIN; _bReleaseInstanceInMainThread = YES; _defaultDataRender = NO; @@ -447,14 +437,9 @@ - (BOOL)_handleConfigCenter if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) { BOOL useCoreText = [[configCenter configForKey:@"iOS_weex_ext_config.text_render_useCoreText" defaultValue:@YES isDefault:NULL] boolValue]; [WXTextComponent setRenderUsingCoreText:useCoreText]; - BOOL useThreadSafeLock = [[configCenter configForKey:@"iOS_weex_ext_config.useThreadSafeLock" defaultValue:@YES isDefault:NULL] boolValue]; - [WXUtility setThreadSafeCollectionUsingLock:useThreadSafeLock]; BOOL unregisterFontWhenCollision = [[configCenter configForKey:@"iOS_weex_ext_config.unregisterFontWhenCollision" defaultValue:@NO isDefault:NULL] boolValue]; [WXUtility setUnregisterFontWhenCollision:unregisterFontWhenCollision]; - - BOOL listSectionRowThreadSafe = [[configCenter configForKey:@"iOS_weex_ext_config.listSectionRowThreadSafe" defaultValue:@(YES) isDefault:NULL] boolValue]; - [WXUtility setListSectionRowThreadSafe:listSectionRowThreadSafe]; BOOL useJSCApiForCreateInstance = [[configCenter configForKey:@"iOS_weex_ext_config.useJSCApiForCreateInstance" defaultValue:@(YES) isDefault:NULL] boolValue]; [WXUtility setUseJSCApiForCreateInstance:useJSCApiForCreateInstance]; @@ -663,25 +648,22 @@ - (void)destroyInstance [WXPrerenderManager destroyTask:self.instanceId]; [[WXSDKManager bridgeMgr] destroyInstance:self.instanceId]; - __weak typeof(self) weakSelf = self; + WXComponentManager* componentManager = self.componentManager; + NSString* instanceId = self.instanceId; + WXPerformBlockOnComponentThread(^{ - __strong typeof(self) strongSelf = weakSelf; - if (strongSelf == nil) { - return; - } - // Destroy components and views in main thread. Unbind with underneath RenderObjects. - [strongSelf.componentManager unload]; + [componentManager unload]; // Destroy weexcore c++ page and objects. - [WXCoreBridge closePage:strongSelf.instanceId]; + [WXCoreBridge closePage:instanceId]; // Reading config from orange for Release instance in Main Thread or not, for Bug #15172691 +{ if (!_bReleaseInstanceInMainThread) { - [WXSDKManager removeInstanceforID:strongSelf.instanceId]; + [WXSDKManager removeInstanceforID:instanceId]; } else { dispatch_async(dispatch_get_main_queue(), ^{ - [WXSDKManager removeInstanceforID:strongSelf.instanceId]; + [WXSDKManager removeInstanceforID:instanceId]; }); } //+} @@ -690,8 +672,6 @@ - (void)destroyInstance if (url.length > 0) { [WXPrerenderManager addGlobalTask:url callback:nil]; } - - _isRendered = NO; } - (void)forceGarbageCollection diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableArray.h b/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableArray.h index a164076e3e..9009dfffc9 100644 --- a/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableArray.h +++ b/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableArray.h @@ -24,4 +24,28 @@ */ @interface WXThreadSafeMutableArray : NSMutableArray +- (instancetype)init; +- (instancetype)initWithCapacity:(NSUInteger)numItems; +- (instancetype)initWithArray:(NSArray *)array; +- (instancetype)initWithCoder:(NSCoder *)aDecoder; +- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt; + +- (NSUInteger)count; +- (id)objectAtIndex:(NSUInteger)index; +- (id)objectAtIndexedSubscript:(NSUInteger)index; +- (id)firstObject; +- (id)lastObject; +- (BOOL)containsObject:(id)anObject; +- (NSEnumerator *)objectEnumerator; +- (NSEnumerator *)reverseObjectEnumerator; +- (void)insertObject:(id)anObject atIndex:(NSUInteger)index; +- (void)setObject:(id)anObject atIndexedSubscript:(NSUInteger)index; +- (void)addObject:(id)anObject; +- (void)removeObject:(id)anObject; +- (void)removeObjectAtIndex:(NSUInteger)index; +- (void)removeLastObject; +- (void)removeAllObjects; +- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject; +- (NSUInteger)indexOfObject:(id)anObject; + @end diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableArray.m b/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableArray.m index b1724af47c..1d76158f98 100644 --- a/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableArray.m +++ b/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableArray.m @@ -18,18 +18,15 @@ */ #import "WXThreadSafeMutableArray.h" -#import "WXUtility.h" -#import #import -@interface WXThreadSafeMutableArray () { +@interface WXThreadSafeMutableArray () +{ + NSMutableArray* _array; pthread_mutex_t _safeThreadArrayMutex; pthread_mutexattr_t _safeThreadArrayMutexAttr; } -@property (nonatomic, strong) dispatch_queue_t queue; -@property (nonatomic, strong) NSMutableArray* array; - @end @implementation WXThreadSafeMutableArray @@ -38,10 +35,8 @@ - (instancetype)initCommon { self = [super init]; if (self) { - NSString* uuid = [NSString stringWithFormat:@"com.taobao.weex.array_%p", self]; - _queue = dispatch_queue_create([uuid UTF8String], DISPATCH_QUEUE_CONCURRENT); pthread_mutexattr_init(&(_safeThreadArrayMutexAttr)); - pthread_mutexattr_settype(&(_safeThreadArrayMutexAttr), PTHREAD_MUTEX_RECURSIVE); + pthread_mutexattr_settype(&(_safeThreadArrayMutexAttr), PTHREAD_MUTEX_DEFAULT); pthread_mutex_init(&(_safeThreadArrayMutex), &(_safeThreadArrayMutexAttr)); } return self; @@ -65,11 +60,11 @@ - (instancetype)initWithCapacity:(NSUInteger)numItems return self; } -- (NSArray *)initWithContentsOfFile:(NSString *)path +- (instancetype)initWithArray:(NSArray *)array { self = [self initCommon]; if (self) { - _array = [NSMutableArray arrayWithContentsOfFile:path]; + _array = [NSMutableArray arrayWithArray:array]; } return self; } @@ -97,140 +92,204 @@ - (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt - (NSUInteger)count { - __block NSUInteger count; - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_sync(_queue, ^{ - count = _array.count; - }); - } else { + @try { pthread_mutex_lock(&_safeThreadArrayMutex); - count = [_array count]; + return [_array count]; + } + @finally { pthread_mutex_unlock(&_safeThreadArrayMutex); } - return count; } - (id)objectAtIndex:(NSUInteger)index { - __block id obj; - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_sync(_queue, ^{ - obj = _array[index]; - }); - } else { + @try { + pthread_mutex_lock(&_safeThreadArrayMutex); + return [_array objectAtIndex:index]; + } + @finally { + pthread_mutex_unlock(&_safeThreadArrayMutex); + } +} + +- (id)objectAtIndexedSubscript:(NSUInteger)index +{ + @try { + pthread_mutex_lock(&_safeThreadArrayMutex); + return [_array objectAtIndexedSubscript:index]; + } + @finally { + pthread_mutex_unlock(&_safeThreadArrayMutex); + } +} + +- (id)firstObject +{ + @try { + pthread_mutex_lock(&_safeThreadArrayMutex); + return [_array firstObject]; + } + @finally { + pthread_mutex_unlock(&_safeThreadArrayMutex); + } +} + +- (id)lastObject +{ + @try { pthread_mutex_lock(&_safeThreadArrayMutex); - obj = _array[index]; + return [_array lastObject]; + } + @finally { pthread_mutex_unlock(&_safeThreadArrayMutex); } - return obj; } -- (NSEnumerator *)keyEnumerator +- (BOOL)containsObject:(id)anObject { - __block NSEnumerator *enu; - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_sync(_queue, ^{ - enu = [_array objectEnumerator]; - }); - } else { + @try { pthread_mutex_lock(&_safeThreadArrayMutex); - enu = [_array objectEnumerator]; + return [_array containsObject:anObject]; + } + @finally { + pthread_mutex_unlock(&_safeThreadArrayMutex); + } +} + +- (NSEnumerator *)objectEnumerator +{ + @try { + pthread_mutex_lock(&_safeThreadArrayMutex); + return [_array objectEnumerator]; + } + @finally { + pthread_mutex_unlock(&_safeThreadArrayMutex); + } +} + +- (NSEnumerator *)reverseObjectEnumerator +{ + @try { + pthread_mutex_lock(&_safeThreadArrayMutex); + return [_array reverseObjectEnumerator]; + } + @finally { pthread_mutex_unlock(&_safeThreadArrayMutex); } - return enu; } - (void)insertObject:(id)anObject atIndex:(NSUInteger)index { - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_barrier_async(_queue, ^{ - [_array insertObject:anObject atIndex:index]; - }); - } else { + @try { pthread_mutex_lock(&_safeThreadArrayMutex); [_array insertObject:anObject atIndex:index]; + } + @finally { + pthread_mutex_unlock(&_safeThreadArrayMutex); + } +} + +- (void)setObject:(id)anObject atIndexedSubscript:(NSUInteger)index +{ + @try { + pthread_mutex_lock(&_safeThreadArrayMutex); + [_array setObject:anObject atIndexedSubscript:index]; + } + @finally { pthread_mutex_unlock(&_safeThreadArrayMutex); } } -- (void)addObject:(id)anObject; +- (void)addObject:(id)anObject { - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_barrier_async(_queue, ^{ - [_array addObject:anObject]; - }); - } else { + @try { pthread_mutex_lock(&_safeThreadArrayMutex); [_array addObject:anObject]; + } + @finally { + pthread_mutex_unlock(&_safeThreadArrayMutex); + } +} + +- (void)removeObject:(id)anObject +{ + @try { + pthread_mutex_lock(&_safeThreadArrayMutex); + [_array removeObject:anObject]; + } + @finally { pthread_mutex_unlock(&_safeThreadArrayMutex); } } - (void)removeObjectAtIndex:(NSUInteger)index { - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_barrier_async(_queue, ^{ - [_array removeObjectAtIndex:index]; - }); - } else { + @try { pthread_mutex_lock(&_safeThreadArrayMutex); [_array removeObjectAtIndex:index]; + } + @finally { pthread_mutex_unlock(&_safeThreadArrayMutex); } } - (void)removeLastObject { - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_barrier_async(_queue, ^{ - [_array removeLastObject]; - }); - } else { + @try { pthread_mutex_lock(&_safeThreadArrayMutex); [_array removeLastObject]; + } + @finally { + pthread_mutex_unlock(&_safeThreadArrayMutex); + } +} + +- (void)removeAllObjects +{ + @try { + pthread_mutex_lock(&_safeThreadArrayMutex); + [_array removeAllObjects]; + } + @finally { pthread_mutex_unlock(&_safeThreadArrayMutex); } } - (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject { - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_barrier_async(_queue, ^{ - [_array replaceObjectAtIndex:index withObject:anObject]; - }); - } else { + @try { pthread_mutex_lock(&_safeThreadArrayMutex); [_array replaceObjectAtIndex:index withObject:anObject]; + } + @finally { pthread_mutex_unlock(&_safeThreadArrayMutex); } } - (NSUInteger)indexOfObject:(id)anObject { - __block NSUInteger index = NSNotFound; - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_sync(_queue, ^{ - for (int i = 0; i < [_array count]; i ++) { - if ([_array objectAtIndex:i] == anObject) { - index = i; - break; - } - } - }); - } else { + @try { pthread_mutex_lock(&_safeThreadArrayMutex); - index = [_array indexOfObject:anObject]; + return [_array indexOfObject:anObject]; + } + @finally { pthread_mutex_unlock(&_safeThreadArrayMutex); } - - return index; } -- (void)dealloc +- (id)copy { - if (_queue) { - _queue = NULL; + @try { + pthread_mutex_lock(&_safeThreadArrayMutex); + return [_array copy]; + } + @finally { + pthread_mutex_unlock(&_safeThreadArrayMutex); } +} + +- (void)dealloc +{ pthread_mutex_destroy(&_safeThreadArrayMutex); pthread_mutexattr_destroy(&_safeThreadArrayMutexAttr); } diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableDictionary.h b/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableDictionary.h index 3d9afaefd1..10be43efb7 100644 --- a/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableDictionary.h +++ b/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableDictionary.h @@ -24,4 +24,21 @@ */ @interface WXThreadSafeMutableDictionary : NSMutableDictionary +- (instancetype)init; +- (instancetype)initWithCapacity:(NSUInteger)numItems; +- (instancetype)initWithDictionary:(NSDictionary *)dictionary; +- (instancetype)initWithCoder:(NSCoder *)aDecoder; +- (instancetype)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(NSUInteger)cnt; + +- (NSUInteger)count; +- (id)objectForKey:(id)key; +- (id)objectForKeyedSubscript:(id)key; +- (NSEnumerator *)keyEnumerator; +- (void)setObject:(id)anObject forKey:(id)aKey; +- (void)setObject:(id)anObject forKeyedSubscript:(id )key; +- (NSArray *)allKeys; +- (NSArray *)allValues; +- (void)removeObjectForKey:(id)aKey; +- (void)removeAllObjects; + @end diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableDictionary.m b/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableDictionary.m index d85037ed79..f62e410a35 100644 --- a/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableDictionary.m +++ b/ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableDictionary.m @@ -18,51 +18,25 @@ */ #import "WXThreadSafeMutableDictionary.h" -#import "WXUtility.h" #import -#import @interface WXThreadSafeMutableDictionary () { + NSMutableDictionary* _dict; pthread_mutex_t _safeThreadDictionaryMutex; pthread_mutexattr_t _safeThreadDictionaryMutexAttr; } -@property (nonatomic, strong) dispatch_queue_t queue; -@property (nonatomic, strong) NSMutableDictionary* dict; - @end -#define OVERRIDE_METHOD(method,retValue) \ -do { \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \ - if (![WXUtility threadSafeCollectionUsingLock]) {\ - dispatch_sync(_queue, ^{\ - if ([_dict respondsToSelector:method]) {\ - retValue = [_dict performSelector:method];\ - }\ - });\ - } else {\ - pthread_mutex_lock(&_safeThreadDictionaryMutex);\ - if ([_dict respondsToSelector:method]) {\ - retValue = [_dict performSelector:method];\ - }\ - pthread_mutex_unlock(&_safeThreadDictionaryMutex);\ - }\ - _Pragma("clang diagnostic pop")\ -} while (0) - @implementation WXThreadSafeMutableDictionary - (instancetype)initCommon { self = [super init]; if (self) { - NSString* uuid = [NSString stringWithFormat:@"com.taobao.weex.dictionary_%p", self]; - _queue = dispatch_queue_create([uuid UTF8String], DISPATCH_QUEUE_CONCURRENT); pthread_mutexattr_init(&(_safeThreadDictionaryMutexAttr)); - pthread_mutexattr_settype(&(_safeThreadDictionaryMutexAttr), PTHREAD_MUTEX_RECURSIVE); + pthread_mutexattr_settype(&(_safeThreadDictionaryMutexAttr), PTHREAD_MUTEX_DEFAULT); pthread_mutex_init(&(_safeThreadDictionaryMutex), &(_safeThreadDictionaryMutexAttr)); } return self; @@ -86,11 +60,11 @@ - (instancetype)initWithCapacity:(NSUInteger)numItems return self; } -- (NSDictionary *)initWithContentsOfFile:(NSString *)path +- (instancetype)initWithDictionary:(NSDictionary *)dictionary { self = [self initCommon]; if (self) { - _dict = [NSMutableDictionary dictionaryWithContentsOfFile:path]; + _dict = [NSMutableDictionary dictionaryWithDictionary:dictionary]; } return self; } @@ -119,119 +93,131 @@ - (instancetype)initWithObjects:(const id [])objects forKeys:(const id)aKey { - aKey = [aKey copyWithZone:NULL]; - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_barrier_async(_queue, ^{ - _dict[aKey] = anObject; - }); - } else { + @try { pthread_mutex_lock(&_safeThreadDictionaryMutex); - _dict[aKey] = anObject; + [_dict setObject:anObject forKey:aKey]; + } + @finally { + pthread_mutex_unlock(&_safeThreadDictionaryMutex); + } +} + +- (void)setObject:(id)anObject forKeyedSubscript:(id )key +{ + @try { + pthread_mutex_lock(&_safeThreadDictionaryMutex); + [_dict setObject:anObject forKeyedSubscript:key]; + } + @finally { pthread_mutex_unlock(&_safeThreadDictionaryMutex); } } - (NSArray *)allKeys { - __block NSArray *allKeys = nil; - OVERRIDE_METHOD(_cmd, allKeys); - return allKeys; + @try { + pthread_mutex_lock(&_safeThreadDictionaryMutex); + return [_dict allKeys]; + } + @finally { + pthread_mutex_unlock(&_safeThreadDictionaryMutex); + } } - (NSArray *)allValues { - __block NSArray *allValues = nil; - OVERRIDE_METHOD(_cmd, allValues); - return allValues; + @try { + pthread_mutex_lock(&_safeThreadDictionaryMutex); + return [_dict allValues]; + } + @finally { + pthread_mutex_unlock(&_safeThreadDictionaryMutex); + } } - (void)removeObjectForKey:(id)aKey { - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_barrier_async(_queue, ^{ - [_dict removeObjectForKey:aKey]; - }); - } else { + @try { pthread_mutex_lock(&_safeThreadDictionaryMutex); [_dict removeObjectForKey:aKey]; + } + @finally { pthread_mutex_unlock(&_safeThreadDictionaryMutex); } } - (void)removeAllObjects { - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_barrier_async(_queue, ^{ - [_dict removeAllObjects]; - }); - }else { + @try { pthread_mutex_lock(&_safeThreadDictionaryMutex); [_dict removeAllObjects]; + } + @finally { pthread_mutex_unlock(&_safeThreadDictionaryMutex); } } -- (id)copy{ - __block id copyInstance; - if (![WXUtility threadSafeCollectionUsingLock]) { - dispatch_sync(_queue, ^{ - copyInstance = [_dict copy]; - }); - } else { +- (id)copy +{ + @try { pthread_mutex_lock(&_safeThreadDictionaryMutex); - copyInstance = [_dict copy]; + return [_dict copy]; + } + @finally { pthread_mutex_unlock(&_safeThreadDictionaryMutex); } - - return copyInstance; } - (void)dealloc diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h index 1fa68335b7..601727a6eb 100644 --- a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h +++ b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.h @@ -483,20 +483,12 @@ BOOL WXFloatGreaterThanWithPrecision(CGFloat a,CGFloat b,double precision); */ + (NSData *_Nonnull)base64DictToData:(NSDictionary *_Nullable)base64Dict; -+ (void)setThreadSafeCollectionUsingLock:(BOOL)usingLock; - -+ (BOOL)threadSafeCollectionUsingLock; - + (void)setUnregisterFontWhenCollision:(BOOL)value; -+ (void)setListSectionRowThreadSafe:(BOOL)value; - + (void)setUseJSCApiForCreateInstance:(BOOL)value; + (BOOL)useJSCApiForCreateInstance; -+ (BOOL)listSectionRowThreadSafe; - + (long) getUnixFixTimeMillis; + (NSArray *_Nullable)extractPropertyNamesOfJSValueObject:(JSValue *_Nullable)jsvalue; diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m index 097e3798dc..121a73c9c2 100644 --- a/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m +++ b/ios/sdk/WeexSDK/Sources/Utility/WXUtility.m @@ -42,9 +42,7 @@ #define KEY_PASSWORD @"com.taobao.Weex.123456" #define KEY_USERNAME_PASSWORD @"com.taobao.Weex.weex123456" -static BOOL threadSafeCollectionUsingLock = YES; static BOOL unregisterFontWhenCollision = NO; -static BOOL listSectionRowThreadSafe = YES; static BOOL useJSCApiForCreateInstance = YES; void WXPerformBlockOnMainThread(void (^ _Nonnull block)(void)) @@ -141,31 +139,11 @@ CGFloat WXFloorPixelValue(CGFloat value) @implementation WXUtility -+ (void)setThreadSafeCollectionUsingLock:(BOOL)usingLock -{ - threadSafeCollectionUsingLock = usingLock; -} - -+ (BOOL)threadSafeCollectionUsingLock -{ - return threadSafeCollectionUsingLock; -} - + (void)setUnregisterFontWhenCollision:(BOOL)value { unregisterFontWhenCollision = value; } -+ (void)setListSectionRowThreadSafe:(BOOL)value -{ - listSectionRowThreadSafe = value; -} - -+ (BOOL)listSectionRowThreadSafe -{ - return listSectionRowThreadSafe; -} - + (void)setUseJSCApiForCreateInstance:(BOOL)value { useJSCApiForCreateInstance = value; diff --git a/ios/sdk/WeexSDK/Sources/Utility/WXVersion.m b/ios/sdk/WeexSDK/Sources/Utility/WXVersion.m index aef6efc273..c034b1b9ab 100644 --- a/ios/sdk/WeexSDK/Sources/Utility/WXVersion.m +++ b/ios/sdk/WeexSDK/Sources/Utility/WXVersion.m @@ -20,8 +20,8 @@ #import "WXVersion.h" #import "WXDefine.h" -static const char* WeexSDKBuildTime = "2018-09-20 09:52:40 UTC"; -static const unsigned long WeexSDKBuildTimestamp = 1537437160; +static const char* WeexSDKBuildTime = "2018-11-06 06:35:19 UTC"; +static const unsigned long WeexSDKBuildTimestamp = 1541486119; NSString* GetWeexSDKVersion(void) {