iOS: remove mutable copy (may caused alloc exception when oom)

use barrier async dispatch queue to avoid multi-threading error
This commit is contained in:
王劲鹏 2021-07-09 15:58:25 +08:00 committed by osborn
parent 5224df5369
commit fc28d3b90d

View File

@ -22,18 +22,27 @@
@interface DoricNotificationPlugin () @interface DoricNotificationPlugin ()
@property(nonatomic, strong) NSDictionary<NSString *, id> *observers; @property(nonatomic, strong) NSMutableDictionary<NSString *, id> *observers;
@property (nonatomic, strong) dispatch_queue_t syncQuene;
@end @end
@implementation DoricNotificationPlugin @implementation DoricNotificationPlugin
- (NSDictionary *)observers { - (NSDictionary *)observers {
if (!_observers) { if (!_observers) {
_observers = [NSDictionary new]; _observers = [NSMutableDictionary new];
} }
return _observers; return _observers;
} }
- (dispatch_queue_t)syncQuene {
if (!_syncQuene) {
_syncQuene = dispatch_queue_create("pub.doric.plugin.notification", DISPATCH_QUEUE_CONCURRENT);
}
return _syncQuene;
}
- (void)publish:(NSDictionary *)dic withPromise:(DoricPromise *)promise { - (void)publish:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
NSString *biz = [dic optString:@"biz"]; NSString *biz = [dic optString:@"biz"];
NSString *name = [dic optString:@"name"]; NSString *name = [dic optString:@"name"];
@ -70,26 +79,33 @@ - (void)subscribe:(NSDictionary *)dic withPromise:(DoricPromise *)promise {
DoricPromise *currentPromise = [[DoricPromise alloc] initWithContext:self.doricContext callbackId:callbackId]; DoricPromise *currentPromise = [[DoricPromise alloc] initWithContext:self.doricContext callbackId:callbackId];
[currentPromise resolve:note.userInfo]; [currentPromise resolve:note.userInfo];
}]; }];
NSMutableDictionary *mutableDictionary = [self.observers mutableCopy];
mutableDictionary[callbackId] = observer; dispatch_barrier_async(self.syncQuene, ^{
self.observers = mutableDictionary; [self.observers setObject:observer forKey:callbackId];
});
[promise resolve:callbackId]; [promise resolve:callbackId];
} }
- (void)unsubscribe:(NSString *)subscribeId withPromise:(DoricPromise *)promise { - (void)unsubscribe:(NSString *)subscribeId withPromise:(DoricPromise *)promise {
id observer = self.observers[subscribeId]; __block id observer = nil;
dispatch_sync(self.syncQuene, ^{
observer = [self.observers objectForKey:subscribeId];
});
if (observer) { if (observer) {
[[NSNotificationCenter defaultCenter] removeObserver:observer]; [[NSNotificationCenter defaultCenter] removeObserver:observer];
NSMutableDictionary *mutableDictionary = [self.observers mutableCopy]; dispatch_barrier_async(self.syncQuene, ^{
[mutableDictionary removeObjectForKey:subscribeId]; [self.observers removeObjectForKey:subscribeId];
self.observers = mutableDictionary; });
} }
[promise resolve:nil]; [promise resolve:nil];
} }
- (void)dealloc { - (void)dealloc {
NSDictionary *dictionary = self.observers; __block NSArray *values;
[dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { dispatch_sync(self.syncQuene, ^{
values = [self.observers allValues];
});
[values enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) {
[[NSNotificationCenter defaultCenter] removeObserver:obj]; [[NSNotificationCenter defaultCenter] removeObserver:obj];
}]; }];
} }