Ios CLLocationManager响应性
我有一个应用程序,它围绕着设备的GPS和来自它的信息。位置数据必须准确且最新,这一点很重要。我知道该设备受到GPS和GPS的限制,但我想知道我是否可以做些什么来调整/改进iPhone GPS的性能,特别是在速度方面。由于位置更新滞后于设备的实时位置约3-5秒,因此位置管理器报告的速度也远远滞后于实时值。就我而言,这实在太长了。我知道我可能无能为力,但有人成功地提高了iPhone GPS的响应能力吗?每一点点都会带来不同 编辑1: 正如苹果公司推荐的那样,我的位置管理器在一个单例类中 在SingletonDataController.m中:Ios CLLocationManager响应性,ios,performance,gps,core-location,cllocationmanager,Ios,Performance,Gps,Core Location,Cllocationmanager,我有一个应用程序,它围绕着设备的GPS和来自它的信息。位置数据必须准确且最新,这一点很重要。我知道该设备受到GPS和GPS的限制,但我想知道我是否可以做些什么来调整/改进iPhone GPS的性能,特别是在速度方面。由于位置更新滞后于设备的实时位置约3-5秒,因此位置管理器报告的速度也远远滞后于实时值。就我而言,这实在太长了。我知道我可能无能为力,但有人成功地提高了iPhone GPS的响应能力吗?每一点点都会带来不同 编辑1: 正如苹果公司推荐的那样,我的位置管理器在一个单例类中 在Singl
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内部(实际使用位置管理器的位置):
数据处理发生在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];
}
-(void)setLabels:(CLLocation*)newLocation fromOldLocation:(CLLocation*)oldLocation{
//设置速度标签
如果(迭代次数>0){
如果(currentSpeed>KeysppeedFilter){
如果(如下所示){
[mapViewGlobal setRegion:mkCoordinatereRegionMake([newLocation coordinate],mapViewGlobal.region.span)];
}
NSString*currentSpeedString;
如果(是定制的){
currentSpeedString=[[NSString alloc]initWithFormat:@“%.1f英里/小时”(currentSpeed*2.23693629f)];
}否则{
currentSpeedString=[[NSString alloc]initWithFormat:@“%.1f公里/小时”(currentSpeed*3.6f)];
}
[speedLabel setText:currentSpeedString];
[当前速度字符串释放];
}否则{
speedLabel.text=@“未移动”;
}
}
//设置平均速度标签
如果(迭代次数>4&&movementIterations>2){
NSString*平均速度字符串;
如果(是定制的){
averageSpeedString=[[NSString alloc]initWithFormat:@“%.1f英里/小时”,(浮动)((速度平均值/(长双精度)移动迭代)*2.23693629f)];
}否则{
averageSpeedString=[[NSString alloc]initWithFormat:@“%.1f公里/小时”,(浮动)((速度平均值/(长双)移动迭代)*3.6f)];
}
[averageSpeedLabel setText:averageSpeedString];
[平均速度字符串释放];
}
//设置运行时间标签
NSInteger seconds=[[NSDate date]timeIntervalSinceDate:dataObject.locationManagerStartDate];
NSInteger分=秒/60;
NSInteger小时=分钟/60;
//得到余数
秒%=60;
NSString*时间字符串;
NSString*第二个字符串;
NSString*分钟字符串;
NSString*小时字符串;
如果((秒%60)<10){
secondsString=[[NSString alloc]initWithFormat:@“0%i”,秒];
}否则{
secondsString=[[NSString alloc]initWithFormat:@“%i”,秒];
}
如果((分钟%60)<10){
MinuteString=[[NSString alloc]initWithFormat:@“0%i”,分钟];
}否则{
MinuteString=[[NSString alloc]initWithFormat:@“%i”,分钟];
}
如果((小时数%60)<10){
hoursString=[[NSString alloc]initWithFormat:@“0%i”,小时];
}否则{
hoursString=[[NSString alloc]initWithFormat:@“%i”,小时];
}
timeString=[[NSString alloc]initWithFormat:@“%@:%@:%@”,小时字符串,分钟字符串,秒字符串];
[elapsedTimeLabel setText:timeString];
[timeString release],timeString=nil;
[secondsString释放],secondsString=nil;
[分钟字符串释放],分钟字符串=零;
[hoursString释放],hoursString=nil;
NSString*总距离;
如果(是定制的){
TotalDistancesting=[[NSString alloc]initWithFormat:@“总计:%.2f mi”,(浮点)距离*0.000621371192f];
}否则{
TotalDistancesting=[[NSString alloc]initWithFormat:@“总计:%.2f公里,(浮动)距离/1000.0f];
}
[customTopBar设置标题:TotalDistancesting];
[总释放量];
}
通过几个NSDate和NSLogs,我发现在我的iPhone 4上执行整个
locationManager:didUpdateToLocation:fromLocation:
(不仅仅是标签更新方法)的时间不会超过8毫秒;换句话说,数据处理不是问题。好的,有几件事可以改善滞后。首先,始终使用KCllocationAccuracybest进行导航。这与kCLLocationAccuracyBest之间没有实际的电池使用差异,它们都以最高速度使用GPS。主要区别在于苹果的后处理
其次,不需要过滤速度==0。苹果已经做了这种过滤:如果你的GPS速度低于某个阈值(约4公里/小时),操作系统会假设你站着不动,并用相同的位置值替换所有后续样本。它会一直这样做,直到它认为你再次移动。我想他们这样做是为了避免你站着不动时在地图上“抖动”。事实上,对于“静止”值序列的最后一个实数值,速度已经下降到0,因此,如果过滤速度==0,则会丢失一个真实的GPS样本
不幸的是,他们无法避免这种过滤并获得真正的GPS样本。我和苹果谈过这件事,他们的反应是他们不会改变这种行为。kCLLocationAccuracyBestForNavigation的过滤不如kCLLocationAccuracyBest,所以最好使用它
第三,您可能已经在这样做了,但请确保在vi上调用“setNeedsDisplay”
- (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];
}
kCLLocationAccuracyBestForNavigation
kCLLocationAccuracyBest
kCLLocationAccuracyNearestTenMeters
kCLLocationAccuracyHundredMeters
kCLLocationAccuracyKilometer
kCLLocationAccuracyThreeKilometers
Note: If you try with different accuracy and different distance filter value then you will be more clear about it how accurate data iPhone GPS hardware return.