我需要一种“调度一次”机制,当所有条件都满足时,假设 A 和 B 都为真,运行该部分代码一次,但只运行一次。因此,稍后,如果再次满足所有条件(A 和 B 都再次为真,但我不在乎),代码将不会再次运行。
我认为 dispatch_once 不适合这里。这里没有数据同步问题,只是稍后可能会再次满足所有条件。现在我尝试两种方法:
- KVO 所有条件,一旦满足,运行代码并停止 KVO。
- 添加另一个属性,在满足某些条件时更新它。当满足所有条件时,运行代码,然后将其设置为一个特殊值,这将防止代码再次运行。比如设置它的初始值为1,当A为真&2,当B为真&4,那么当它为7时,运行代码将它的值设置为0。那么以后,它就再也不会是7了。
那么有更好的方法吗?
----更新----
除了知道有多少方法可以做到这一点,我也在寻找一种“系统”的方法来做到这一点。现在我需要在 A 和 B 都为真时运行一次第 1 部分;第 2 部分一次,当 C&D&E 为真时;第 3 部分一次,当 E&F 为真时。我使用了我提到的两种方法。代码看起来很乱,其他人很难理解我要完成的事情。
最佳答案
假设您希望这种情况在每个应用程序中只发生一次,我认为没有任何问题:
- (void)tryOnce{
if (a && b){
dispatch_once()...
}
}
如何确定何时运行 if
完全取决于您的具体实现。在 a
和 b
上使用 KVO 似乎是合适的,如果它们可以在多个位置修改,或者您可以覆盖 setter :
- (void)setA(id a) {
_a = a;
[self tryOnce];
}
- (void)setB(id B) {
_b = b;
[self tryOnce];
}
--- 编辑 OP 更新 ---
一个通用的解决方案是创建一个包含两个 block 并覆盖 observeValueForKeypath:...
的类。这可以让你避免在你的(可能)UIViewController 的 observeValueForKeyPath
中进行大量困惑的检查,并且通常是一个很好的模式,无论你发现自己处理对同一方法的许多调用(UITextView 委托(delegate)等......) .
@implementation ObserveAndDoOnce
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
if (!self.checkBlock || !self.finishedBlock){ return; }
if (self.checkBlock()) { // checkBlock returns a BOOL
self.finishedBlock();
self.checkBlock = nil;
self.finishedBlock = nil;
}
}
@end
ObserveAndDoOnce *a_and_b = [ObserveAndDoOnce new];
[self addObserver:a_and_b forKeyPath:keypath_for_a...];
[self addObserver:a_and_b forKeyPath:keypath_for_b...];
a_and_b.checkBlock = ...
a_and_b.finishedBlock = ...
关于ios - 我如何实现一个 "dispatch_once"方法,不是针对多线程环境,而是在满足所有条件时只运行一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42546909/