为啥我不能用这个代码读取设备与磁北的偏差?

Posted

技术标签:

【中文标题】为啥我不能用这个代码读取设备与磁北的偏差?【英文标题】:Why can't I read the device's deviation from the magnetic North with this code?为什么我不能用这个代码读取设备与磁北的偏差? 【发布时间】:2012-07-30 14:08:49 【问题描述】:

好的,代码现在可以工作了,但它仍然需要工作。我得到的值是“粘性的”,它们不稳定(每次我尝试返回时,磁北似乎都会移动一点),我需要稍微摇动设备以刷新/唤醒价值观..

游戏.h

#import <Foundation/Foundation.h>

#import "CoreLocation.h"

@interface Game : NSObject

<CLLocationManagerDelegate>

@property BOOL stopButtonPressed;

-(void) play;

@end

游戏.m

@implementation Game

- (id) init 

    self = [super init];

    self.stopButtonPressed = NO;

    CLLocationManager *locationManager;

    locationManager = [[CLLocationManager alloc] init];

    locationManager.delegate = self;

    return self;


-(void) play 


    [locationManager startUpdatingHeading]; 

    while(!self.stopButtonPressed)
    
         double degrees = locationManager.heading.magneticHeading;

         int degreesRounded = (int)degrees;

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


@end

MyViewController.m

@interface MyViewController()

    Game *game;

@end

@implementation MyViewController

-(void) viewDidLoad

    game = [[Game alloc] init];


- (IBAction)playPressed:(UIButton *)sender 

    [game performSelectorInBackground:@selector(play) withObject:nil];


- (IBAction)stopPressed:(UIButton *)sender 

    game.stopButtonPressed = YES;


@end

我做错了什么?

【问题讨论】:

【参考方案1】:

此代码将阻塞线程,如果它发生在主线程中,您将永远无法按下按钮。

CLLocationManager 是一种异步机制。要正确使用它,您必须提供一个委托,它会在位置更新可用时通知该委托(在大多数情况下可以是 self(其中 self 是 viewController 或类似的)。请参阅 CLLocationManagerDelegate docs

...
    CLLocationManager *locationManager;
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    [locationManager startUpdatingHeading];


- (void)locationManager:manager didUpdateHeading:newHeading 
    double degrees = newHeading.magneticHeading;
     NSLog(@"Degrees : %F", degrees);

【讨论】:

它似乎没有阻塞主线程,我在控制台上得到“标题可用”,然后我一直得到“度数:0.000” 对,无限循环。它没有被冻结,只是这段代码不会让其他任何事情发生。 我也在一个单独的线程中运行的 -(void) play 方法中执行所有这些:'[game performSelectorInBackground:@selector(play) withObject:nil];' 啊,所以它没有阻塞main 线程,这意味着您仍然可以按下按钮并退出该循环。更好的;但答案的本质仍然是您的最佳选择:利用 CLLocationManagerDelegate 回调:-) 我编辑了我的原始帖子并包含了我的整个代码,以便您更好地了解我在做什么。我是 Obj-C 的新手,我不确定委派是如何工作的。我会尝试在我的代码中实现你的代码,看看我得到了什么..【参考方案2】:

您应该捕获CLLocationManager 委托方法,而不是直接调用属性:https://developer.apple.com/library/mac/#documentation/CoreLocation/Reference/CLLocationManagerDelegate_Protocol/CLLocationManagerDelegate/CLLocationManagerDelegate.html#//apple_ref/occ/intf/CLLocationManagerDelegate

【讨论】:

以上是关于为啥我不能用这个代码读取设备与磁北的偏差?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 c++ ifstream 不能从设备读取?

为啥有些设备不能用 SetupDiGetDeviceInterfaceDetail() 枚举?

为啥我不能用 operator>> 读取 fstream 的二进制数据?

为啥 response.body 不能用 xlsx 格式读取

为啥我们不能在不添加偏差或将其转换为 2 或 1 补码的情况下存储 IEEE 浮点数的指数? [复制]

为啥我不能用这个表单将数据插入我的数据库?