是否可以在执行一组代码之前检查条件是否在一定时间内连续成立? 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
编辑:我只想对所有帮助过的人说声谢谢!
由于不知道你的真实意图,我提出了一个涵盖场景的桥接解决方案。
首先将 x
和 y
声明为 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;
}
总结一下:
- 我们捕获每一帧的加速度计更新。
- 在 0.5 秒后安排
takePicture
例程
- 在
takePicture
例程中重新评估条件,如果它仍然成立
是的,我们执行捕获代码。
那还剩下什么?这里我们只考虑了终止条件——我们评估了 0.5 秒间隔开始之前和结束之后的条件。但它不能保证条件在两者之间保持 true
。如果我们也需要符合这种情况,如果条件偏离其 true
状态,我们需要取消先前安排的例程,这可以通过取消注释运动管理器更新部分中的 else
块来实现我暂时注释掉了。
例如,假设某些变量根据用户输入而变化。当此变量达到某个条件时,它必须在执行其他代码之前保持该条件一段时间。
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
编辑:我只想对所有帮助过的人说声谢谢!
由于不知道你的真实意图,我提出了一个涵盖场景的桥接解决方案。
首先将 x
和 y
声明为 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;
}
总结一下:
- 我们捕获每一帧的加速度计更新。
- 在 0.5 秒后安排
takePicture
例程 - 在
takePicture
例程中重新评估条件,如果它仍然成立 是的,我们执行捕获代码。
那还剩下什么?这里我们只考虑了终止条件——我们评估了 0.5 秒间隔开始之前和结束之后的条件。但它不能保证条件在两者之间保持 true
。如果我们也需要符合这种情况,如果条件偏离其 true
状态,我们需要取消先前安排的例程,这可以通过取消注释运动管理器更新部分中的 else
块来实现我暂时注释掉了。