Objective-C多Delegate无顺序回调 如何不用布尔变量触发后续方法
解决方案
确实存在无需自定义布尔实例变量的实现方案,以下是几种常见的原生实现方式:
方案1:使用GCD调度组(dispatch_group)
这是兼容性最好的方案,支持iOS 4.0+系统,不需要引入第三方依赖:
// 类扩展中定义调度组实例变量 @interface YourClass () @property (nonatomic, assign) dispatch_group_t delegateCallbackGroup; @end @implementation YourClass - (instancetype)init { if (self = [super init]) { _delegateCallbackGroup = dispatch_group_create(); // 提前为两个待执行的回调各enter一次 dispatch_group_enter(_delegateCallbackGroup); dispatch_group_enter(_delegateCallbackGroup); // 组内所有任务都leave后触发回调 dispatch_group_notify(_delegateCallbackGroup, dispatch_get_main_queue(), ^{ [self whenBothMethodsFinished]; }); } return self; } - (void)updatedAppleLists { // 你的原有业务逻辑 dispatch_group_leave(self.delegateCallbackGroup); } - (void)updatedOrangeLists { // 你的原有业务逻辑 dispatch_group_leave(self.delegateCallbackGroup); } - (void)whenBothMethodsFinished { NSLog(@"Both are updated"); // 如果需要支持下一轮同步,在这里重新初始化group并enter两次即可 } @end
这个方案的优势是后续如果新增回调需要同步,只需要多调用一次dispatch_group_enter即可,扩展性远优于手动维护多个布尔变量,也避免了布尔变量拼写错误(你原有代码里的isUpdatedOrrages就存在拼写错误,容易引发线上bug)。
方案2:使用Combine框架(iOS 13+支持)
如果你的App最低支持iOS 13,可以用Combine的合并操作符实现,完全不需要自己维护任何状态变量:
#import <Combine/Combine.h> @interface YourClass () @property (nonatomic, strong) PassthroughSubject<Void, Never> *appleUpdateSubject; @property (nonatomic, strong) PassthroughSubject<Void, Never> *orangeUpdateSubject; @property (nonatomic, strong) id cancellable; @end @implementation YourClass - (instancetype)init { if (self = [super init]) { _appleUpdateSubject = [PassthroughSubject new]; _orangeUpdateSubject = [PassthroughSubject new]; // 合并两个信号,都收到值后触发后续操作 _cancellable = [NSCombineLatest2(_appleUpdateSubject, _orangeUpdateSubject) subscribeNext:^(id _Nullable x) { [self whenBothMethodsFinished]; }]; } return self; } - (void)updatedAppleLists { // 你的原有业务逻辑 [self.appleUpdateSubject send:nil]; } - (void)updatedOrangeLists { // 你的原有业务逻辑 [self.orangeUpdateSubject send:nil]; } - (void)whenBothMethodsFinished { NSLog(@"Both are updated"); } @end
方案3:使用NSOperation依赖
你也可以用NSOperationQueue的依赖机制实现:
@interface YourClass () @property (nonatomic, strong) NSOperationQueue *operationQueue; @property (nonatomic, strong) NSOperation *appleUpdateOp; @property (nonatomic, strong) NSOperation *orangeUpdateOp; @property (nonatomic, strong) NSOperation *finishOp; @end @implementation YourClass - (instancetype)init { if (self = [super init]) { _operationQueue = [[NSOperationQueue alloc] init]; _operationQueue.maxConcurrentOperationCount = 1; _appleUpdateOp = [NSBlockOperation blockOperationWithBlock:^{}]; _orangeUpdateOp = [NSBlockOperation blockOperationWithBlock:^{}]; _finishOp = [NSBlockOperation blockOperationWithBlock:^{ [self whenBothMethodsFinished]; }]; // 给完成操作添加依赖,必须等前两个操作都完成才执行 [_finishOp addDependency:_appleUpdateOp]; [_finishOp addDependency:_orangeUpdateOp]; [_operationQueue addOperation:_finishOp]; } return self; } - (void)updatedAppleLists { // 你的原有业务逻辑 [self.operationQueue addOperation:self.appleUpdateOp]; } - (void)updatedOrangeLists { // 你的原有业务逻辑 [self.operationQueue addOperation:self.orangeUpdateOp]; } - (void)whenBothMethodsFinished { NSLog(@"Both are updated"); } @end
内容的提问来源于stack exchange,提问作者Kumar KL
相关产品推荐
相关产品推荐

