iOS:fix when obj_retain DoricContext cause crash
This commit is contained in:
parent
a7e042174f
commit
3fa9124801
@ -111,8 +111,7 @@ - (void)onConnectExceptionEvent {
|
|||||||
- (void)onStartDebugEvent:(NSNotification *)notification {
|
- (void)onStartDebugEvent:(NSNotification *)notification {
|
||||||
NSString *contextId = notification.object;
|
NSString *contextId = notification.object;
|
||||||
ShowToast(contextId, DoricGravityBottom);
|
ShowToast(contextId, DoricGravityBottom);
|
||||||
for (NSValue *value in [[DoricContextManager instance] aliveContexts]) {
|
for (DoricContext *context in [[DoricContextManager instance] aliveContexts]) {
|
||||||
DoricContext *context = value.nonretainedObjectValue;
|
|
||||||
BOOL result = [context.contextId compare:contextId] == NSOrderedSame;
|
BOOL result = [context.contextId compare:contextId] == NSOrderedSame;
|
||||||
if (result) {
|
if (result) {
|
||||||
_context = context;
|
_context = context;
|
||||||
|
@ -58,17 +58,18 @@ - (void)viewDidLoad {
|
|||||||
[self.navigationController pushViewController:[QRScanViewController new] animated:NO];
|
[self.navigationController pushViewController:[QRScanViewController new] animated:NO];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)onClose {
|
- (void)onClose {
|
||||||
[[DoricDev instance] closeDevMode];
|
[[DoricDev instance] closeDevMode];
|
||||||
[self.navigationController popViewControllerAnimated:YES];
|
[self.navigationController popViewControllerAnimated:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
|
||||||
return [DoricContextManager.instance aliveContexts].count;
|
return [DoricContextManager.instance aliveContexts].count;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
NSValue *value = [DoricContextManager.instance aliveContexts][(NSUInteger) indexPath.row];
|
DoricContext *context = [DoricContextManager.instance aliveContexts][(NSUInteger) indexPath.row];
|
||||||
DoricContext *context = value.nonretainedObjectValue;
|
|
||||||
NSString *path = context.source;
|
NSString *path = context.source;
|
||||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
|
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
|
||||||
if (cell == nil) {
|
if (cell == nil) {
|
||||||
@ -84,8 +85,7 @@ - (BOOL)isSimulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
NSValue *value = [DoricContextManager.instance aliveContexts][(NSUInteger) indexPath.row];
|
DoricContext *context = [DoricContextManager.instance aliveContexts][(NSUInteger) indexPath.row];
|
||||||
DoricContext *context = value.nonretainedObjectValue;
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"StartDebugEvent" object:context.contextId];
|
[[NSNotificationCenter defaultCenter] postNotificationName:@"StartDebugEvent" object:context.contextId];
|
||||||
NSDictionary *jsonDic = @{
|
NSDictionary *jsonDic = @{
|
||||||
@"cmd": @"DEBUG",
|
@"cmd": @"DEBUG",
|
||||||
|
@ -64,8 +64,7 @@ - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message {
|
|||||||
} else if ([cmd compare:@"RELOAD"] == NSOrderedSame) {
|
} else if ([cmd compare:@"RELOAD"] == NSOrderedSame) {
|
||||||
NSString *source = [[dic valueForKey:@"source"] mutableCopy];
|
NSString *source = [[dic valueForKey:@"source"] mutableCopy];
|
||||||
NSString *script = [dic valueForKey:@"script"];
|
NSString *script = [dic valueForKey:@"script"];
|
||||||
for (NSValue *value in [[DoricContextManager instance] aliveContexts]) {
|
for (DoricContext *context in [[DoricContextManager instance] aliveContexts]) {
|
||||||
DoricContext *context = value.nonretainedObjectValue;
|
|
||||||
if ([source containsString:context.source] || [context.source isEqualToString:@"__dev__"]) {
|
if ([source containsString:context.source] || [context.source isEqualToString:@"__dev__"]) {
|
||||||
[context reload:script];
|
[context reload:script];
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||||||
|
|
||||||
- (DoricContext *)getContext:(NSString *)contextId;
|
- (DoricContext *)getContext:(NSString *)contextId;
|
||||||
|
|
||||||
- (NSArray *)aliveContexts;
|
- (NSArray <DoricContext *> *)aliveContexts;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
@interface DoricContextManager ()
|
@interface DoricContextManager ()
|
||||||
|
|
||||||
@property(nonatomic) NSInteger counter;
|
@property(nonatomic) NSInteger counter;
|
||||||
@property(nonatomic, strong) NSMutableDictionary <NSString *, NSValue *> *doricContextMap;
|
@property(nonatomic, strong) NSMapTable <NSString *, DoricContext *> *contextMapTable;
|
||||||
@property(nonatomic, strong) dispatch_queue_t mapQueue;
|
@property(nonatomic, strong) dispatch_queue_t mapQueue;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@ -33,9 +33,11 @@ @implementation DoricContextManager
|
|||||||
|
|
||||||
- (instancetype)init {
|
- (instancetype)init {
|
||||||
if (self = [super init]) {
|
if (self = [super init]) {
|
||||||
_doricContextMap = [[NSMutableDictionary alloc] init];
|
|
||||||
_counter = 0;
|
_counter = 0;
|
||||||
_mapQueue = dispatch_queue_create("doric.contextmap", DISPATCH_QUEUE_SERIAL);
|
_mapQueue = dispatch_queue_create("doric.contextmap", DISPATCH_QUEUE_SERIAL);
|
||||||
|
_contextMapTable = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsCopyIn
|
||||||
|
valueOptions:NSPointerFunctionsWeakMemory
|
||||||
|
capacity:0];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -52,8 +54,7 @@ + (instancetype)instance {
|
|||||||
- (void)createContext:(DoricContext *)context script:(NSString *)script source:(NSString *)source {
|
- (void)createContext:(DoricContext *)context script:(NSString *)script source:(NSString *)source {
|
||||||
context.contextId = [NSString stringWithFormat:@"%ld", (long) ++self.counter];
|
context.contextId = [NSString stringWithFormat:@"%ld", (long) ++self.counter];
|
||||||
dispatch_sync(self.mapQueue, ^() {
|
dispatch_sync(self.mapQueue, ^() {
|
||||||
NSValue *value = [NSValue valueWithNonretainedObject:context];
|
[self.contextMapTable setObject:context forKey:context.contextId];
|
||||||
self.doricContextMap[context.contextId] = value;
|
|
||||||
});
|
});
|
||||||
[context.driver createContext:context.contextId script:script source:source];
|
[context.driver createContext:context.contextId script:script source:source];
|
||||||
}
|
}
|
||||||
@ -61,8 +62,7 @@ - (void)createContext:(DoricContext *)context script:(NSString *)script source:(
|
|||||||
- (DoricContext *)getContext:(NSString *)contextId {
|
- (DoricContext *)getContext:(NSString *)contextId {
|
||||||
__block DoricContext *context;
|
__block DoricContext *context;
|
||||||
dispatch_sync(self.mapQueue, ^{
|
dispatch_sync(self.mapQueue, ^{
|
||||||
NSValue *value = self.doricContextMap[contextId];
|
context = [self.contextMapTable objectForKey:contextId];
|
||||||
context = value.nonretainedObjectValue;
|
|
||||||
});
|
});
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
@ -70,12 +70,18 @@ - (DoricContext *)getContext:(NSString *)contextId {
|
|||||||
- (void)destroyContext:(DoricContext *)context {
|
- (void)destroyContext:(DoricContext *)context {
|
||||||
NSString *contextId = context.contextId;
|
NSString *contextId = context.contextId;
|
||||||
dispatch_sync(self.mapQueue, ^() {
|
dispatch_sync(self.mapQueue, ^() {
|
||||||
[self.doricContextMap removeObjectForKey:contextId];
|
[self.contextMapTable removeObjectForKey:contextId];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *)aliveContexts {
|
- (NSArray <DoricContext *> *)aliveContexts {
|
||||||
return [self.doricContextMap allValues];
|
NSEnumerator *enumerator = [self.contextMapTable objectEnumerator];
|
||||||
|
NSMutableArray *ret = [NSMutableArray new];
|
||||||
|
DoricContext *context;
|
||||||
|
while ((context = [enumerator nextObject])) {
|
||||||
|
[ret addObject:context];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -34,7 +34,7 @@ @implementation DoricBridgeExtension
|
|||||||
|
|
||||||
- (id)callNativeWithContextId:(NSString *)contextId module:(NSString *)module method:(NSString *)method callbackId:(NSString *)callbackId argument:(id)argument {
|
- (id)callNativeWithContextId:(NSString *)contextId module:(NSString *)module method:(NSString *)method callbackId:(NSString *)callbackId argument:(id)argument {
|
||||||
__strong DoricContext *context = [[DoricContextManager instance] getContext:contextId];
|
__strong DoricContext *context = [[DoricContextManager instance] getContext:contextId];
|
||||||
if (context.destroyed) {
|
if (!context || context.destroyed) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
Class pluginClass = [self.registry acquireNativePlugin:module];
|
Class pluginClass = [self.registry acquireNativePlugin:module];
|
||||||
|
Reference in New Issue
Block a user