Ios CLLocationManager响应性

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

我有一个应用程序,它围绕着设备的GPS和来自它的信息。位置数据必须准确且最新,这一点很重要。我知道该设备受到GPS和GPS的限制,但我想知道我是否可以做些什么来调整/改进iPhone GPS的性能,特别是在速度方面。由于位置更新滞后于设备的实时位置约3-5秒,因此位置管理器报告的速度也远远滞后于实时值。就我而言,这实在太长了。我知道我可能无能为力,但有人成功地提高了iPhone GPS的响应能力吗?每一点点都会带来不同

编辑1:

正如苹果公司推荐的那样,我的位置管理器在一个单例类中

在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内部(实际使用位置管理器的位置):

数据处理发生在
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.