Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 为什么我总是从磁场属性得到0度?_Iphone_Objective C_Ios_Magnetometer - Fatal编程技术网

Iphone 为什么我总是从磁场属性得到0度?

Iphone 为什么我总是从磁场属性得到0度?,iphone,objective-c,ios,magnetometer,Iphone,Objective C,Ios,Magnetometer,我正试图通过仅仅依靠设备的磁强计来获得设备从磁北的磁偏角,以度为单位。这是我写的代码,但我只得到0度。。我做错了什么 CMMotionManager *motionManager; motionManager = [[CMMotionManager alloc] init]; [motionManager startDeviceMotionUpdates]; CMDeviceMotion *deviceMotion; deviceMotion = [[CMDeviceMotion all

我正试图通过仅仅依靠设备的磁强计来获得设备从磁北的磁偏角,以度为单位。这是我写的代码,但我只得到0度。。我做错了什么

CMMotionManager *motionManager;

motionManager = [[CMMotionManager alloc] init];

[motionManager startDeviceMotionUpdates];

CMDeviceMotion *deviceMotion;

deviceMotion = [[CMDeviceMotion alloc] init];

while(!self.stopButtonPressed)
{
    double x = motionManager.deviceMotion.magneticField.field.x;

    double y = motionManager.deviceMotion.magneticField.field.y;

    double degrees = asin(y/sqrt(pow(x, 2.0) + pow(y, 2.0))) * 180.0 / M_PI ;

    int degreesRounded = (int)degrees;

    NSLog(@"Degrees : %i", degreesRounded);
}

很可能模拟器不会返回这些方法的正常值,因此您需要在真实设备上进行测试

CLLocationManager
的方法,
didUpdateHeading:
在模拟器上不起作用,因此您可能会遇到类似的情况

编辑:

从文档中:

“设备运动数据的最新示例。(只读)

@属性(只读)CMDeviceMotion*deviceMotion

讨论 如果没有可用的设备运动数据,则此属性的值为零。调用StartDeviceMotionUpdate后接收设备运动数据的应用程序会定期检查此属性的值并处理设备运动数据。”

检查运动管理器的属性是否为零。如果是,那么磁场属性将为0

编辑2:

您应该使用
startMagnetometerUpdatesToQueue:
,而不是使用
startDeviceMotionUpdates
。文件说:

磁强计。设置MagnetometrUpdateInterval属性以指定更新间隔。调用startMagnetometerUpdatesToQueue:withHandler:方法,传递CMMagnetometerHandler类型的块。磁场数据作为CMMagnetometerData对象传递到块中


文档是。

上面的代码运行在哪个线程上?如果您在主线程上运行它,那么随着时间的推移,您可能无法看到设备运动数据的更新。使用NSTimer或类似的机制随时间对运动进行采样,这样主线程就可以自由地做其他事情(例如来自core motion子系统的服务请求)。

以下是我在真实设备上测试的内容:

   CMMotionManager *myMotionManager= [[CMMotionManager alloc] init];
    myMotionManager.deviceMotionUpdateInterval = 1;
    [myMotionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXMagneticNorthZVertical  toQueue:[NSOperationQueue currentQueue] withHandler:^(CMDeviceMotion *motion, NSError *error) {
        double x = myMotionManager.deviceMotion.magneticField.field.x;
        double y = myMotionManager.deviceMotion.magneticField.field.y;
        double z = myMotionManager.deviceMotion.magneticField.field.z;
        NSLog(@"Field.x= %f; Field.y = %f; Field.z= %f",x,y,z);
    }];

我正在一个真实的设备上测试,为什么设备的运动数据不可用,因为我使用的是一个带有工作磁强计的iPhone4S?这没道理,我不想排队。我想在我要求时直接实时访问magneticField.field.x和magneticField.field.y的值。并且每次循环都以相同的方式获取新值。文档:“您的应用程序可以从startMagnetometerUpdatesToQueue:withHandler:方法的块处理程序或CMMotionManager类的magnetometerData属性中获取磁强计测量的样本,如该类的实例所示”Is
motionManager.deviceMotion
nil?看起来像是nil。我写了while(motionManager.deviceMotion!=nil){…循环…},现在在我点击Play后应用程序将停止。您是否获得
x
y
的真实值?您使用的是什么设备?并非所有iOS设备都有磁强计。
asin(y/sqrt(pow(x,2.0)+pow(y,2.0))
相当于
atan(y/fabs(x))
…这仅用于测试目的。我创建了一个名为Game的类,它只有一个-(void)play方法,该方法中包含的所有内容都是我上面介绍的代码。当应用程序运行时,调用一个游戏实例的play方法,就是这样..我试图澄清我的答案;如果你在你的主线程上运行一个无限循环,你可能不会得到核心运动数据,因为核心运动可能使用主线程的runloop。不,我实际上已经尝试了上面的形式,但不是在我的while循环中要求磁场值,而是从陀螺仪中要求偏航值,效果很好,使用CoreMotion类。这种数据仍然可能需要主线程。在这两种情况下,是否有可能需要校准磁场值?尝试将
showsDeviceMovementDisplay
设置为YES,或侦听
cmErrorDeviceRequestesmovement
错误。我将其设置为YES,但仍然没有得到任何结果。作为编程新手,我对主线程和非主线程知之甚少。如何将所有这些代码放在一个单独的线程中,与主线程并行运行?但我仍然相信我还有别的地方做错了。。