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:
parent
5224df5369
commit
fc28d3b90d
@ -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];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user