1

代码正在努力获取运动和陀螺仪更新,分别放入数组并在发生捕获事件时选择数组中的最大值。如果设备运动更新设置为 .02 或 .03,则一切正常;但是,当更新设置为我的应用程序所需的 .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

`

4

1 回答 1

0

只是想为有类似问题的任何人分享解决方案。在上面的 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 时,设备运动更新似乎比代码执行更快。

于 2014-08-25T19:32:00.380 回答