代码正在努力获得运动和陀螺仪更新,分别放入数组中,并在捕获事件发生时选择数组中的最大值。如果设备运动更新设置为0.02或0.03,一切都行得通;但是,当更新设置为应用程序所需的0.01时,我将获得额外的输出/值。任何帮助或指导将非常感激。提前感谢。代码如下:'
#import "ViewController.h"
#import <CoreMotion/CoreMotion.h>
#define kRadToDeg 57.2957795
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *pitchLabel;
@property (nonatomic, strong) CMMotionManager *motionManager;
@property (weak, nonatomic) IBOutlet UILabel *rotationXLabel;
@property (nonatomic, strong) CMDeviceMotion *motion;
@property (nonatomic, strong) NSMutableArray *pitchArray;
@property (nonatomic, strong) NSMutableArray *rotationArray;
@property (nonatomic) id maxRotation;
@property (nonatomic) id maxPitch;
@property BOOL captureValues;
@end
@implementation ViewController
- (CMMotionManager *)motionManager
{
if (!_motionManager) {
_motionManager = [CMMotionManager new];
[_motionManager setDeviceMotionUpdateInterval:(.01)];
[_motionManager setGyroUpdateInterval:(.01)];
}
return _motionManager;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self placePitchValuesInArray];
[self placeRotationValuesInArray];
}
-(void)placePitchValuesInArray {
NSMutableArray *pitchArray = [NSMutableArray array];
pitchArray = [[NSMutableArray alloc] initWithCapacity:150];
if (_captureValues == NO) {
[self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
self.pitchLabel.text = [NSString stringWithFormat:@"%.2gº", motion.attitude.pitch * kRadToDeg];
[pitchArray addObject:[NSString stringWithFormat:@"%.2gº", motion.attitude.pitch * kRadToDeg]];
_pitchArray = pitchArray;
if (pitchArray.count >= 150) { //maintain running array of 150 pitch values
[pitchArray removeObjectAtIndex:0];
}
id maxPitch = [_rotationArray valueForKeyPath:@"@max.intValue"];
_maxPitch = maxPitch;
[self checkCapture];
}];
}
}
-(void)placeRotationValuesInArray {
NSMutableArray *rotationArray = [NSMutableArray array];
rotationArray = [[NSMutableArray alloc] initWithCapacity:150 ];
if (self.captureValues == NO) {
[self.motionManager startGyroUpdatesToQueue:[NSOperationQueue currentQueue] withHandler:^(CMGyroData *gyroData, NSError *error) {
self.rotationXLabel.text = [NSString stringWithFormat:@"%f", gyroData.rotationRate.x];
[rotationArray addObject:[NSString stringWithFormat:@"%f", gyroData.rotationRate.x]];
_rotationArray = rotationArray;
if (rotationArray.count >= 150) { //maintain running array of 150 rotaion values
[rotationArray removeObjectAtIndex:0];
}
id maxRotation = [rotationArray valueForKeyPath:@"@max.intValue"];
_maxRotation = maxRotation;
[self checkCapture];
}];
}
}
-(void)checkCapture {
//to generate capture. iPhone is landscape with HOME button on RIGHT. Tilt left side UP slightly. ROTATE quickly in a counter-clockwise fashion.
if (([self.pitchLabel.text integerValue] > 3) && ([self.rotationXLabel.text integerValue] > 5))
{
(_captureValues = YES);
[_motionManager stopDeviceMotionUpdates];
[_motionManager stopGyroUpdates];
for (int i=0; i<30; i++){ // modify pitchArray to remove last 30 values
[self.pitchArray removeLastObject];
}
id maxPitch = [_pitchArray valueForKeyPath:@"@max.integerValue"];
_maxPitch = maxPitch;
[self outputValues];
}
}
-(void)outputValues {
NSLog(@"Max Pitch Value from modified array = %@", _maxPitch);
NSLog(@"Max Rotation Value = %@", _maxRotation);
sleep(2.5);
[self resetFlagAndArrays];
}
-(void)resetFlagAndArrays {
(_captureValues = NO);
[_pitchArray removeAllObjects];
[_rotationArray removeAllObjects];
[self viewDidLoad];
}
@end
"
只是想为有类似问题的人分享解决方案。在上面的checkCapture方法中停止设备运动更新后,我添加了一个延迟,并将"for循环"移动到一个单独的方法中——如下所示:
[self performSelector:@selector(adjustValues) withObject:nil afterDelay:.5];
-(void)adjustValues {
for (int i=0; i<30; i++){ // modify pitchArray to remove last 30 values
[self.pitchArray removeLastObject];
}
id maxPitch = [_pitchArray valueForKeyPath:@"@max.integerValue"];
_maxPitch = maxPitch;
[self outputValues];
}
这解决了数据"泄漏"的问题,因为当更新间隔设置为0.01时,设备运动更新似乎比代码的执行速度更快。