Skip to content
This repository was archived by the owner on Jun 3, 2021. It is now read-only.

Commit dbde671

Browse files
wqyfavorcxfeng1
authored andcommitted
[iOS] Fix ios mutlithread related issues. Refactor WXThreadSafeMutableXXX containers. (#1716)
1 parent 04eee5c commit dbde671

16 files changed

+284
-255
lines changed

ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#import "WXSDKManager.h"
3131
#import "WXDebugTool.h"
3232
#import "WXSDKInstance_private.h"
33-
#import "WXThreadSafeMutableArray.h"
3433
#import "WXAppConfiguration.h"
3534
#import "WXInvocationConfig.h"
3635
#import "WXComponentMethod.h"

ios/sdk/WeexSDK/Sources/Component/WXListComponent.mm

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#import "WXSDKInstance_private.h"
3232
#import "WXRefreshComponent.h"
3333
#import "WXLoadingComponent.h"
34-
#import "WXThreadSafeMutableArray.h"
3534

3635
@interface WXTableView : UITableView
3736

@@ -95,12 +94,8 @@ @implementation WXSectionComponent
9594
- (instancetype)init
9695
{
9796
if (self = [super init]) {
98-
if ([WXUtility listSectionRowThreadSafe]) {
99-
_rows = [WXThreadSafeMutableArray array];
100-
} else {
101-
_rows = [NSMutableArray array];
102-
} }
103-
97+
_rows = [NSMutableArray array];
98+
}
10499
return self;
105100
}
106101

ios/sdk/WeexSDK/Sources/Controller/WXRootViewController.m

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,13 @@
1919

2020
#import "WXRootViewController.h"
2121
#import "WXBaseViewController.h"
22-
#import "WXThreadSafeMutableArray.h"
2322
#import "WXDefine.h"
2423

2524
typedef void(^OperationBlock)(void);
2625

2726
@interface WXRootViewController() <UIGestureRecognizerDelegate>
2827

29-
@property(nonatomic, strong) WXThreadSafeMutableArray *operationArray;
28+
@property (nonatomic, strong) NSMutableArray *operationArray;
3029
@property (nonatomic, assign) BOOL operationInProcess;
3130

3231
@end
@@ -131,11 +130,10 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
131130
return YES;
132131
}
133132

134-
- (NSMutableArray *)pendingBlocks
133+
- (NSMutableArray *)operationArray
135134
{
136-
137135
if (nil == _operationArray) {
138-
_operationArray = [[WXThreadSafeMutableArray alloc] init];
136+
_operationArray = [[NSMutableArray alloc] init];
139137
}
140138

141139
return _operationArray;

ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.m

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@
3131
#import "WXTracingManager.h"
3232
#import "WXMonitor.h"
3333
#import "WXSDKInstance_performance.h"
34+
#import "WXThreadSafeMutableArray.h"
3435

3536
@interface WXBridgeManager ()
3637

37-
@property (nonatomic, strong) WXBridgeContext *bridgeCtx;
38-
@property (nonatomic, assign) BOOL stopRunning;
39-
@property (nonatomic, strong) NSMutableArray *instanceIdStack;
38+
@property (nonatomic, assign) BOOL stopRunning;
39+
@property (nonatomic, strong) WXBridgeContext *bridgeCtx;
40+
@property (nonatomic, strong) WXThreadSafeMutableArray *instanceIdStack;
4041

4142
@end
4243

@@ -202,26 +203,24 @@ - (void)createInstance:(NSString *)instance
202203
}
203204

204205

205-
- (NSMutableArray *)instanceIdStack
206+
- (WXThreadSafeMutableArray *)instanceIdStack
206207
{
207208
if (_instanceIdStack) return _instanceIdStack;
208209

209-
_instanceIdStack = [NSMutableArray array];
210+
_instanceIdStack = [[WXThreadSafeMutableArray alloc] init];
210211

211212
return _instanceIdStack;
212213
}
213214

214215
- (NSArray *)getInstanceIdStack;
215216
{
216-
return self.instanceIdStack;
217+
return [self.instanceIdStack copy];
217218
}
218219

219220
- (void)destroyInstance:(NSString *)instance
220221
{
221222
if (!instance) return;
222-
if([self.instanceIdStack containsObject:instance]){
223-
[self.instanceIdStack removeObject:instance];
224-
}
223+
[self.instanceIdStack removeObject:instance];
225224

226225
__weak typeof(self) weakSelf = self;
227226
WXPerformBlockOnBridgeThread(^(){

ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.mm

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,11 @@ - (instancetype)initWithWeexInstance:(id)weexInstance
8989
pthread_mutexattr_init(&_propertMutexAttr);
9090
pthread_mutexattr_settype(&_propertMutexAttr, PTHREAD_MUTEX_RECURSIVE);
9191
pthread_mutex_init(&_propertyMutex, &_propertMutexAttr);
92-
[self _startDisplayLink];
92+
93+
WXPerformBlockOnComponentThread(^{
94+
// We should ensure that [WXDisplayLinkManager sharedInstance] is only invoked in component thread.
95+
[self _startDisplayLink];
96+
});
9397
}
9498

9599
return self;

ios/sdk/WeexSDK/Sources/Manager/WXSDKManager.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ + (void)removeInstanceforID:(NSString *)identifier
8181

8282
+ (void)unload
8383
{
84-
for (NSString *instanceID in [self sharedInstance].instanceDict) {
84+
for (NSString *instanceID in [[self sharedInstance].instanceDict allKeys]) {
8585
WXSDKInstance *instance = [[self sharedInstance].instanceDict objectForKey:instanceID];
8686
[instance destroyInstance];
8787
}

ios/sdk/WeexSDK/Sources/Model/WXComponent.mm

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
#import "WXConvert.h"
3131
#import "WXMonitor.h"
3232
#import "WXAssert.h"
33-
#import "WXThreadSafeMutableDictionary.h"
34-
#import "WXThreadSafeMutableArray.h"
3533
#import "WXTransform.h"
3634
#import "WXRoundedRect.h"
3735
#import <pthread/pthread.h>

ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ extern NSString *const bundleUrlOptionKey;
8282
@property (nonatomic, strong) NSDictionary* containerInfo;
8383

8484
/**
85-
* Whether this instance is rendered or not. Please MUST not render an instance twice.
85+
* Whether this instance is rendered or not. Please MUST not render an instance twice even if you have called destroyInstance.
8686
**/
8787
@property (nonatomic, assign, readonly) BOOL isRendered;
8888

@@ -276,7 +276,7 @@ typedef NS_ENUM(NSInteger, WXErrorCode) {//error.code
276276
- (void)refreshInstance:(id)data;
277277

278278
/**
279-
* Destroys current instance.
279+
* Destroys current instance. An instance destroyed should not be used for rendering again, please create another instance.
280280
**/
281281
- (void)destroyInstance;
282282

ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ @implementation WXSDKInstance
7575
WXRootView *_rootView;
7676
WXThreadSafeMutableDictionary *_moduleEventObservers;
7777
BOOL _performanceCommit;
78-
BOOL _syncDestroyComponentManager;
7978
BOOL _debugJS;
8079
id<WXBridgeProtocol> _instanceJavaScriptContext; // sandbox javaScript context
8180
CGFloat _defaultPixelScaleFactor;
@@ -87,11 +86,6 @@ - (void)dealloc
8786
{
8887
[_moduleEventObservers removeAllObjects];
8988
[self removeObservers];
90-
if (_syncDestroyComponentManager) {
91-
WXPerformBlockSyncOnComponentThread(^{
92-
_componentManager = nil;
93-
});
94-
}
9589
}
9690

9791
- (instancetype)init
@@ -123,10 +117,6 @@ - (instancetype)init
123117
_performance = [[WXPerformance alloc] init];
124118
_apmInstance = [[WXApmForInstance alloc] init];
125119

126-
id configCenter = [WXSDKEngine handlerForProtocol:@protocol(WXConfigCenterProtocol)];
127-
if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) {
128-
_syncDestroyComponentManager = [[configCenter configForKey:@"iOS_weex_ext_config.syncDestroyComponentManager" defaultValue:@(YES) isDefault:NULL] boolValue];
129-
}
130120
_defaultPixelScaleFactor = CGFLOAT_MIN;
131121
_bReleaseInstanceInMainThread = YES;
132122
_defaultDataRender = NO;
@@ -447,14 +437,9 @@ - (BOOL)_handleConfigCenter
447437
if ([configCenter respondsToSelector:@selector(configForKey:defaultValue:isDefault:)]) {
448438
BOOL useCoreText = [[configCenter configForKey:@"iOS_weex_ext_config.text_render_useCoreText" defaultValue:@YES isDefault:NULL] boolValue];
449439
[WXTextComponent setRenderUsingCoreText:useCoreText];
450-
BOOL useThreadSafeLock = [[configCenter configForKey:@"iOS_weex_ext_config.useThreadSafeLock" defaultValue:@YES isDefault:NULL] boolValue];
451-
[WXUtility setThreadSafeCollectionUsingLock:useThreadSafeLock];
452440

453441
BOOL unregisterFontWhenCollision = [[configCenter configForKey:@"iOS_weex_ext_config.unregisterFontWhenCollision" defaultValue:@NO isDefault:NULL] boolValue];
454442
[WXUtility setUnregisterFontWhenCollision:unregisterFontWhenCollision];
455-
456-
BOOL listSectionRowThreadSafe = [[configCenter configForKey:@"iOS_weex_ext_config.listSectionRowThreadSafe" defaultValue:@(YES) isDefault:NULL] boolValue];
457-
[WXUtility setListSectionRowThreadSafe:listSectionRowThreadSafe];
458443

459444
BOOL useJSCApiForCreateInstance = [[configCenter configForKey:@"iOS_weex_ext_config.useJSCApiForCreateInstance" defaultValue:@(YES) isDefault:NULL] boolValue];
460445
[WXUtility setUseJSCApiForCreateInstance:useJSCApiForCreateInstance];
@@ -663,25 +648,22 @@ - (void)destroyInstance
663648
[WXPrerenderManager destroyTask:self.instanceId];
664649
[[WXSDKManager bridgeMgr] destroyInstance:self.instanceId];
665650

666-
__weak typeof(self) weakSelf = self;
651+
WXComponentManager* componentManager = self.componentManager;
652+
NSString* instanceId = self.instanceId;
653+
667654
WXPerformBlockOnComponentThread(^{
668-
__strong typeof(self) strongSelf = weakSelf;
669-
if (strongSelf == nil) {
670-
return;
671-
}
672-
673655
// Destroy components and views in main thread. Unbind with underneath RenderObjects.
674-
[strongSelf.componentManager unload];
656+
[componentManager unload];
675657

676658
// Destroy weexcore c++ page and objects.
677-
[WXCoreBridge closePage:strongSelf.instanceId];
659+
[WXCoreBridge closePage:instanceId];
678660

679661
// Reading config from orange for Release instance in Main Thread or not, for Bug #15172691 +{
680662
if (!_bReleaseInstanceInMainThread) {
681-
[WXSDKManager removeInstanceforID:strongSelf.instanceId];
663+
[WXSDKManager removeInstanceforID:instanceId];
682664
} else {
683665
dispatch_async(dispatch_get_main_queue(), ^{
684-
[WXSDKManager removeInstanceforID:strongSelf.instanceId];
666+
[WXSDKManager removeInstanceforID:instanceId];
685667
});
686668
}
687669
//+}
@@ -690,8 +672,6 @@ - (void)destroyInstance
690672
if (url.length > 0) {
691673
[WXPrerenderManager addGlobalTask:url callback:nil];
692674
}
693-
694-
_isRendered = NO;
695675
}
696676

697677
- (void)forceGarbageCollection

ios/sdk/WeexSDK/Sources/Utility/WXThreadSafeMutableArray.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,28 @@
2424
*/
2525
@interface WXThreadSafeMutableArray : NSMutableArray
2626

27+
- (instancetype)init;
28+
- (instancetype)initWithCapacity:(NSUInteger)numItems;
29+
- (instancetype)initWithArray:(NSArray *)array;
30+
- (instancetype)initWithCoder:(NSCoder *)aDecoder;
31+
- (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt;
32+
33+
- (NSUInteger)count;
34+
- (id)objectAtIndex:(NSUInteger)index;
35+
- (id)objectAtIndexedSubscript:(NSUInteger)index;
36+
- (id)firstObject;
37+
- (id)lastObject;
38+
- (BOOL)containsObject:(id)anObject;
39+
- (NSEnumerator *)objectEnumerator;
40+
- (NSEnumerator *)reverseObjectEnumerator;
41+
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
42+
- (void)setObject:(id)anObject atIndexedSubscript:(NSUInteger)index;
43+
- (void)addObject:(id)anObject;
44+
- (void)removeObject:(id)anObject;
45+
- (void)removeObjectAtIndex:(NSUInteger)index;
46+
- (void)removeLastObject;
47+
- (void)removeAllObjects;
48+
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
49+
- (NSUInteger)indexOfObject:(id)anObject;
50+
2751
@end

0 commit comments

Comments
 (0)