是否可以在执行一组代码之前检查条件是否在一定时间内连续成立? Objective C

Is it possible to check that a condition holds true continuously for a certain duration before executing a set of code? Objective C

例如,假设某些变量根据用户输入而变化。当此变量达到某个条件时,它必须在执行其他代码之前保持该条件一段时间。

if(changingVariable == someValue for some amount of time){
    //code to be executed
}

注意:我希望答案尽可能笼统,以便适用于任何情况。

对于某些上下文,这是我将在以下情况下使用它的情况:

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController
- (CMMotionManager *)motionManager {
    _motionManager = [[CMMotionManager alloc] init];
    _motionManager.accelerometerUpdateInterval = 0.1;
    return _motionManager;
}

- (IBAction)takePhoto:(UIButton *)sender {
    [self isStable];
}

- (void)isStable {
    if(!self.motionManager.isAccelerometerActive) {
        [self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accData, NSError *error){
                CGFloat x = accData.acceleration.x;
                CGFloat y = accData.acceleration.y;
                //CGFloat z = accData.acceleration.z;           
        }];

        // This is the condition that needs to hold true 
        // for half of a second before executing some code 
        if(fabs(x) < .095 && fabs(y) < .095){
            // Code that takes a picture
        }
    }
}
@end

编辑:我只想对所有帮助过的人说声谢谢!

由于不知道你的真实意图,我提出了一个涵盖场景的桥接解决方案。

首先将 xy 声明为 class 属性

@property(nonatomic) CGFloat x;
@property(nonatomic) CGFloat y;
@property(nonatomic) BOOL scheduled;
...

接下来像这样修改你的运动管理器更新代码

[motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accData, NSError *error){
    self.x = accData.acceleration.x;
    self.y = accData.acceleration.y;

    // This is the condition that needs to hold true
    // for half of a second before executing some code
    if(fabs(self.x) < .095 && fabs(self.y) < .095) {
        //schedule your takePicture routine to be executed after 0.5 seconds
        //if not already scheduled
        if (!self.scheduled) {
            [self performSelector:@selector(takePicture) withObject:nil afterDelay:0.5];
            self.scheduled = YES;
        }
    }
    /*
    else {
        //cancel previously scheduled method 
        //if the condition doesn't hold true in an intermediate update
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(takePicture) object:nil];

        //reset the flag so that further scheduling is possible
        self.scheduled = NO;
    }
    */
}];

现在在您的 takePicture 例程中重新评估条件并仅在条件为真时执行代码:

-(void)takePicture {
    if (fabs(self.x) < .095 && fabs(self.y) < .095) {
        // Code that takes a picture
    }

    //reset the flag so that further scheduling is possible
    self.scheduled = NO;
}

总结一下:

  1. 我们捕获每一帧的加速度计更新。
  2. 在 0.5 秒后安排 takePicture 例程
  3. takePicture 例程中重新评估条件,如果它仍然成立 是的,我们执行捕获代码。

那还剩下什么?这里我们只考虑了终止条件——我们评估了 0.5 秒间隔开始之前和结束之后的条件。但它不能保证条件在两者之间保持 true。如果我们也需要符合这种情况,如果条件偏离其 true 状态,我们需要取消先前安排的例程,这可以通过取消注释运动管理器更新部分中的 else 块来实现我暂时注释掉了。