iOS:fix when obj_retain DoricContext cause crash

This commit is contained in:
pengfeizhou
2021-02-09 15:09:52 +08:00
committed by osborn
parent a7e042174f
commit 3fa9124801
6 changed files with 23 additions and 19 deletions

View File

@@ -25,7 +25,7 @@
@interface DoricContextManager ()
@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;
@end
@@ -33,9 +33,11 @@ @implementation DoricContextManager
- (instancetype)init {
if (self = [super init]) {
_doricContextMap = [[NSMutableDictionary alloc] init];
_counter = 0;
_mapQueue = dispatch_queue_create("doric.contextmap", DISPATCH_QUEUE_SERIAL);
_contextMapTable = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsCopyIn
valueOptions:NSPointerFunctionsWeakMemory
capacity:0];
}
return self;
}
@@ -52,8 +54,7 @@ + (instancetype)instance {
- (void)createContext:(DoricContext *)context script:(NSString *)script source:(NSString *)source {
context.contextId = [NSString stringWithFormat:@"%ld", (long) ++self.counter];
dispatch_sync(self.mapQueue, ^() {
NSValue *value = [NSValue valueWithNonretainedObject:context];
self.doricContextMap[context.contextId] = value;
[self.contextMapTable setObject:context forKey:context.contextId];
});
[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 {
__block DoricContext *context;
dispatch_sync(self.mapQueue, ^{
NSValue *value = self.doricContextMap[contextId];
context = value.nonretainedObjectValue;
context = [self.contextMapTable objectForKey:contextId];
});
return context;
}
@@ -70,12 +70,18 @@ - (DoricContext *)getContext:(NSString *)contextId {
- (void)destroyContext:(DoricContext *)context {
NSString *contextId = context.contextId;
dispatch_sync(self.mapQueue, ^() {
[self.doricContextMap removeObjectForKey:contextId];
[self.contextMapTable removeObjectForKey:contextId];
});
}
- (NSArray *)aliveContexts {
return [self.doricContextMap allValues];
- (NSArray <DoricContext *> *)aliveContexts {
NSEnumerator *enumerator = [self.contextMapTable objectEnumerator];
NSMutableArray *ret = [NSMutableArray new];
DoricContext *context;
while ((context = [enumerator nextObject])) {
[ret addObject:context];
}
return ret;
}
@end