gpt4 book ai didi

iphone - CLLocationManager 委托(delegate)在初始化后不工作

转载 作者:可可西里 更新时间:2023-11-01 04:14:29 27 4
gpt4 key购买 nike

我正在尝试使用 rhomobile 框架让 iphone 的指南针工作。我已经完成了 rhomobile 部分,创建了一个可在 iphone 上调用 native 方法的工作包装器,但我无法设法使事件正常工作。

位置管理器.h

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@interface locationController : NSObject <CLLocationManagerDelegate>
{
CLLocationManager *locationManager;
}
@property (strong, nonatomic) CLLocationManager *locationManager;

- (id)init;
- (void)dealloc;

@end

位置管理器.m

#import "Locationmanager.h"

#include "ruby/ext/rho/rhoruby.h"

//store the values
double gx, gy, gz, gth;

//init location
locationController *lc;
@implementation locationController

@synthesize locationManager;

- (id)init {
if (self = [super init]) {
self.locationManager = [[CLLocationManager alloc] init];

NSLog(@"%@", [CLLocationManager headingAvailable]? @"\n\nHeading available!\n" : @"\n\nNo heading..\n");
NSLog(@"%@", [CLLocationManager locationServicesEnabled]? @"\n\nLocation available!\n" : @"\n\nNo location..\n");

// check if the hardware has a compass
if ([CLLocationManager headingAvailable] == NO) {
// No compass is available. This application cannot function without a compass,
// so a dialog will be displayed and no magnetic data will be measured.
locationManager = nil;
UIAlertView *noCompassAlert = [[UIAlertView alloc] initWithTitle:@"No Compass!" message:@"This device does not have the ability to measure magnetic fields." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[noCompassAlert show];
[noCompassAlert release];
NSLog(@"\n***** ERROR *****\n No compass found !!!");
} else {
// setup delegate callbacks
locationManager.delegate = self;

// heading service configuration
locationManager.headingFilter = kCLHeadingFilterNone;

// location service configuration
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;

//start location services
[locationManager startUpdatingLocation];

// start the compass
[locationManager startUpdatingHeading];

}
return self;
}
}
- (void)dealloc {
[super dealloc];
// Stop the compass
[locationManager stopUpdatingHeading];
[locationManager release];
}

// This delegate method is invoked when the location manager has heading data.
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)heading {
NSLog(@"\n\n***** New magnetic heading *****\n %f\n", heading.magneticHeading);
NSLog(@"\n\n***** New true heading *****\n %f\n", heading.trueHeading);
gx = heading.x;
gy = heading.y;
gz = heading.z;
gth = heading.trueHeading;
}

// This delegate method is invoked when the location managed encounters an error condition.
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
if ([error code] == kCLErrorDenied) {
// This error indicates that the user has denied the application's request to use location services.
NSLog(@"\n ***** ERROR *****\n Location not allowed!");
[locationManager stopUpdatingHeading];
} else if ([error code] == kCLErrorHeadingFailure) {
NSLog(@"\n ***** ERROR *****\n Magnetic interference or something!");
}
}

@end

//ruby wrappers
void locationmanager_init(void) {
// make sure we can only start this method once
static bool started = false;
if(!started) {
// Initialize the Objective C accelerometer class.
lc = [[locationController alloc] init];
started = true;
}

}

void locationmanager_get_heading(double *x, double *y, double *z, double *th) {
NSLog(@"\n ***** DEBUGGER *****\n Getting heading x: %f, y: %f, z: %f, heading: %f", gx, gy, gz, gth);
*x = gx;
*y = gy;
*z = gz;
*th = gth;
}

我在装有 iOS 5.1 的 iphone 4 上运行代码,在控制台中我可以看到 init 的调试消息,但我从未看到 didUpdateHeading 委托(delegate)的调试消息。有人知道我在这里错过了什么吗?

更新

我认为我需要在后台线程中运行我的代码才能使其正常工作。目前 locationmanager_init 初始化 + 离开代码,因此它不活跃并且事件没有被触发。任何人都有一个简单的解决方案,可以在后台初始化它以使其保持事件状态?

更新 2

返回了 id,使用了 self = [super init] 仍然没有修复 :(

GitHub code使用 locationmanager_init 初始化,使用 locationmanager_get_heading 检索数据

最佳答案

你必须在主线程上初始化 CLLocationManager,检查这个 SO here ,或从具有事件运行循环的线程运行它,检查此 SO here , 来自 Apple 文档:

Configuration of your location manager object must always occur on a thread with 
an active run loop, such as your application’s main thread.

确保您的 locationController 和其中的 CCLocationManager 在初始化后仍然有效,检查 here .我在这里可能是错的,但从你的 Github 代码来看,似乎 *lc 变量在自动释放池中被释放。尝试给它额外的保留。

lc = [[[locationController alloc] init] retain];

我想这就是您遇到问题的原因。如果该对象已发布,您将不会获得任何更新。

与问题无关但是:

你应该最后而不是首先调用 [super dealloc],检查这个 SO here

将 return 语句放在最后一个括号之前的 init 方法中,而不是倒数第二个之前。

        ...
// start the compass
[locationManager startUpdatingHeading];

}
}
return self;
}

关于iphone - CLLocationManager 委托(delegate)在初始化后不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12218118/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com