ios - 我如何实现一个 "dispatch_once"方法,不是针对多线程环境,而是在满足所有条件时只运行一次

标签 ios multithreading algorithm cocoa key-value-observing

我需要一种“调度一次”机制,当所有条件都满足时,假设 A 和 B 都为真,运行该部分代码一次,但只运行一次。因此,稍后,如果再次满足所有条件(A 和 B 都再次为真,但我不在乎),代码将不会再次运行。

我认为 dispatch_once 不适合这里。这里没有数据同步问题,只是稍后可能会再次满足所有条件。现在我尝试两种方法:

  1. KVO 所有条件,一旦满足,运行代码并停止 KVO。
  2. 添加另一个属性,在满足某些条件时更新它。当满足所有条件时,运行代码,然后将其设置为一个特殊值,这将防止代码再次运行。比如设置它的初始值为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 完全取决于您的具体实现。在 ab 上使用 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/

相关文章:

ios - UICollectionView 移动单元格在单击单元格后还原

ios - PHCachingImageManager.requestImage 总是被调用两次?

C++11 thread::id 表示无线程的特殊值

python 线程 - "condition.wait"和 "condition.notifyAll"是如何工作的

java - 如何测量线程堆栈深度?

c - SPOJ : The day of the competitors

algorithm - Kakuro 和 Subset Sum,其中超集包含连续的正整数,子集的大小固定为 k

ios - 如何搜索特定半径内的位置?

algorithm - 错误的动态规划算法

ios - 两个 TableView 一个数据源?