【发布时间】:2012-04-02 13:14:10
【问题描述】:
我有一个应用程序,它围绕设备的 GPS 和来自它的信息。位置数据准确和最新是很重要的。我知道该设备受到其 GPS 和 GPS 限制的限制,但我想知道是否可以做任何事情来调整/提高 iPhone GPS 的性能,特别是在速度方面。由于位置更新比设备的实时位置滞后约 3-5 秒,因此位置管理器报告的速度也远远落后于实时值。就我而言,这太长了。我知道我可能无能为力,但是有没有人在提高 iPhone GPS 的响应能力方面取得了任何成功?每一点都会有所不同。
编辑 1:
按照 Apple 的建议,我的位置管理器位于单例类中。
SingletonDataController.m 内部:
static CLLocationManager* locationManager;
locationManager = [CLLocationManager new];
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.headingFilter = kCLHeadingFilterNone;
if(([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateCharging) || ([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateFull)) {
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
} else {
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}
[sharedSingleton setLocationManager:locationManager];
[locationManager release];
在 MapView.m 内部(实际使用位置管理器的地方):
- (id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil {
//setup
[SingletonDataController sharedSingleton].locationManager.delegate = self;
//more setup
}
- (void)batteryChanged {
if(([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateCharging) || ([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateFull)) {
[SingletonDataController sharedSingleton].locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
} else {
[SingletonDataController sharedSingleton].locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}
}
- (void)viewDidLoad {
//setup
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(batteryChanged)
name:UIDeviceBatteryStateDidChangeNotification
object:nil];
//other setup
}
数据处理发生在locationManager:didUpdateToLocation:fromLocation: 内部。我不认为这里的低效率是滞后的原因。
locationManager:didUpdateToLocation:fromLocation: 调用此方法更新 UI:
- (void)setLabels:(CLLocation*)newLocation fromOldLocation:(CLLocation*)oldLocation {
//set speed label
if(iterations > 0) {
if(currentSpeed > keyStopSpeedFilter) {
if(isFollowing) {
[mapViewGlobal setRegion:MKCoordinateRegionMake([newLocation coordinate], mapViewGlobal.region.span)];
}
NSString* currentSpeedString;
if(isCustomary) {
currentSpeedString = [[NSString alloc] initWithFormat:@"%.1f miles per hour", (currentSpeed * 2.23693629f)];
} else {
currentSpeedString = [[NSString alloc] initWithFormat:@"%.1f km per hour", (currentSpeed * 3.6f)];
}
[speedLabel setText:currentSpeedString];
[currentSpeedString release];
} else {
speedLabel.text = @"Not moving";
}
}
//set average speed label
if(iterations > 4 && movementIterations > 2) {
NSString* averageSpeedString;
if(isCustomary) {
averageSpeedString = [[NSString alloc] initWithFormat:@"%.1f miles per hour", (float)((speedAverages / (long double)movementIterations) * 2.23693629f)];
} else {
averageSpeedString = [[NSString alloc] initWithFormat:@"%.1f km per hour", (float)((speedAverages / (long double)movementIterations) * 3.6f)];
}
[averageSpeedLabel setText:averageSpeedString];
[averageSpeedString release];
}
//set elapsed time label
NSInteger seconds = [[NSDate date] timeIntervalSinceDate:dataObject.locationManagerStartDate];
NSInteger minutes = seconds / 60;
NSInteger hours = minutes / 60;
//get remainder
seconds %= 60;
NSString* timeString;
NSString* secondsString;
NSString* minutesString;
NSString* hoursString;
if((seconds % 60) < 10) {
secondsString = [[NSString alloc] initWithFormat:@"0%i", seconds];
} else {
secondsString = [[NSString alloc] initWithFormat:@"%i", seconds];
}
if((minutes % 60) < 10) {
minutesString = [[NSString alloc] initWithFormat:@"0%i", minutes];
} else {
minutesString = [[NSString alloc] initWithFormat:@"%i", minutes];
}
if((hours % 60) < 10) {
hoursString = [[NSString alloc] initWithFormat:@"0%i", hours];
} else {
hoursString = [[NSString alloc] initWithFormat:@"%i", hours];
}
timeString = [[NSString alloc] initWithFormat:@"%@:%@:%@", hoursString, minutesString, secondsString];
[elapsedTimeLabel setText:timeString];
[timeString release], timeString = nil;
[secondsString release], secondsString = nil;
[minutesString release], minutesString = nil;
[hoursString release], hoursString = nil;
NSString* totalDistanceString;
if(isCustomary) {
totalDistanceString = [[NSString alloc] initWithFormat:@"Total: %.2f mi", (float)distance * 0.000621371192f];
} else {
totalDistanceString = [[NSString alloc] initWithFormat:@"Total: %.2f km", (float)distance / 1000.0f];
}
[customTopBar setTitle:totalDistanceString];
[totalDistanceString release];
}
通过几个 NSDates 和 NSLogs,我发现在我的 iPhone 4 上执行整个locationManager:didUpdateToLocation:fromLocation:(不仅仅是标签更新方法)不会超过大约 8 毫秒;换句话说,数据处理不是问题。
【问题讨论】:
-
向我们展示您如何获取位置数据。这种滞后是不正常的。
-
添加了代码。如果需要,我可以发布更多内容。
-
3-5 秒可能有点夸张;已经很晚了,范围 3-5 出于某种原因突然出现在我的脑海中。明天我将进行一些测试以获得确切的数字。
-
没什么奇怪的。你在 locationManager:didUpdateToLocation:fromLocation: 中做什么,你是如何确定它滞后的?
-
抱歉,我无法解决延迟问题。但我认为您可以使用 @"%02i" 简化 secondsString/minutesString/hoursString 购买的初始化,以自动格式化前导 0 的数字,而无需显式测试 "
标签: ios performance gps core-location cllocationmanager