CLLocationManager 是否导致此崩溃?

发布于 2024-12-25 11:56:20 字数 4086 浏览 2 评论 0原文

我有一个 UIPickerView 对象,它根据列出的“家庭”位置或当前位置(使用 CLLocationManager)列出商店。如果实现后者,我会向我的服务器发出 NSMutableURLRequest 以获取最近的商店,然后使用收到的列表更新 UIPickerView。

有时(奇怪的是,当我在“家”位置时从来没有),我会使用当前位置,我会看到选择器更新列表,然后应用程序立即崩溃。

我的选择器代码非常简单:

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}

-(NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    if (isHome) {
        return [storesData count];
    } else {
        return [storesDataLoc count];
    }
}

-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    if (isHome) {
        return [[storesData objectAtIndex:row] objectForKey:@"STName"];
    } else {
        return [[storesDataLoc objectAtIndex:row] objectForKey:@"STName"];
    }
}

一个想法是它提供了第二次更准确的读取,并且我正在发布一些我可能已经发布的东西。我的 CLLocationManager 代码是:

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
if (error.code == kCLErrorLocationUnknown) {
    NSLog(@"Currently unable to retrieve location");
} else if (error.code == kCLErrorNetwork) {
    NSLog(@"Network used to retrieve location is unavailable");
} else if (error.code == kCLErrorDenied) {
    NSLog(@"Permission to retrieve location is denied");
    [locMan stopUpdatingLocation];
    [locMan release];
    locMan = nil;

    // revert segmented controller to Home position
    storeSource.selectedSegmentIndex = 0;
}
if(loadstoresconnection!=nil){
    [loadstoresconnection release];
}
networkView.hidden = TRUE;
isHome = TRUE;
}

- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
       fromLocation:(CLLocation *)oldLocation {

if (newLocation.horizontalAccuracy >= 0) {
    networkView.hidden = TRUE;
    if (newLocation.horizontalAccuracy < 200) {
        [locMan stopUpdatingLocation];
        [locMan release];
        locMan = nil;
    }

    //call for store list from this location
    NSString *myString = [NSString stringWithFormat:@"http://mywebsite.com/?lat=%f&lng=%f",newLocation.coordinate.latitude,newLocation.coordinate.longitude];
    NSURL *myURL = [[NSURL alloc] initWithString:[myString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
    loadstoresconnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
}

相关的 NSMutableURLRequest 方法是:

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[responseData release];
[connection release];
networkView.hidden = TRUE;
isHome = YES;
//    [textView setString:@"Unable to fetch data"];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
int i;
NSArray *querydata;

networkView.hidden = TRUE;
[loadstoresconnection release];
if (storesDataLoc!=nil) {
    [storesDataLoc release];
    storesDataLoc = nil;
}
storesDataLoc = [[NSMutableArray alloc] init];
NSString *txt = [[[NSString alloc] initWithData:responseData encoding: NSASCIIStringEncoding] autorelease];
[responseData release];
// put data into variables.
querydata = [txt componentsSeparatedByString:@"<-sl->"];//break up data into data sections: 0 - number of deptsections and names, 1 - list of objects
NSArray *allstoreinfo;
for (i=0; i<[querydata count]; i++) {
    allstoreinfo = [[querydata objectAtIndex:i] componentsSeparatedByString:@"<-as->"];
    [storesDataLoc addObject:[[[NSMutableDictionary alloc] initWithObjectsAndKeys:[allstoreinfo objectAtIndex:0],@"STid",[allstoreinfo objectAtIndex:1],@"STName",[allstoreinfo objectAtIndex:2],@"STAddr",nil] autorelease]];
}
if ([querydata count]>0) {
    [pickerView reload];
    [pickerView selectRow:0 inComponent:0 animated:NO];
    isHome = NO;
}    

}

我很好奇为什么我可以看到选择器在崩溃之前更新。因为这种情况发生在我在路上时,我怀疑这是一个准确性问题,并且位置管理器正在发送第二个结果,导致崩溃。有什么想法吗?

I've got a UIPickerView object that lists stores based on either a listed "home" location or one's current location (using CLLocationManager). If the latter is implemented, I make a NSMutableURLRequest to my server to get the closest stores, then update a UIPickerView with the received list.

On occasion, (and oddly enough never when I'm at the "home" location), I will use the current location, I'll see the picker update the list, then the app immediately crashes.

My picker code is simple enough:

-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}

-(NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
    if (isHome) {
        return [storesData count];
    } else {
        return [storesDataLoc count];
    }
}

-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
    if (isHome) {
        return [[storesData objectAtIndex:row] objectForKey:@"STName"];
    } else {
        return [[storesDataLoc objectAtIndex:row] objectForKey:@"STName"];
    }
}

One thought was that it was providing a second, more accurate reading and that I was releasing something that I may have already released. My CLLocationManager code is:

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
if (error.code == kCLErrorLocationUnknown) {
    NSLog(@"Currently unable to retrieve location");
} else if (error.code == kCLErrorNetwork) {
    NSLog(@"Network used to retrieve location is unavailable");
} else if (error.code == kCLErrorDenied) {
    NSLog(@"Permission to retrieve location is denied");
    [locMan stopUpdatingLocation];
    [locMan release];
    locMan = nil;

    // revert segmented controller to Home position
    storeSource.selectedSegmentIndex = 0;
}
if(loadstoresconnection!=nil){
    [loadstoresconnection release];
}
networkView.hidden = TRUE;
isHome = TRUE;
}

- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
       fromLocation:(CLLocation *)oldLocation {

if (newLocation.horizontalAccuracy >= 0) {
    networkView.hidden = TRUE;
    if (newLocation.horizontalAccuracy < 200) {
        [locMan stopUpdatingLocation];
        [locMan release];
        locMan = nil;
    }

    //call for store list from this location
    NSString *myString = [NSString stringWithFormat:@"http://mywebsite.com/?lat=%f&lng=%f",newLocation.coordinate.latitude,newLocation.coordinate.longitude];
    NSURL *myURL = [[NSURL alloc] initWithString:[myString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
    loadstoresconnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
}

And the pertinent NSMutableURLRequest methods are:

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[responseData release];
[connection release];
networkView.hidden = TRUE;
isHome = YES;
//    [textView setString:@"Unable to fetch data"];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
int i;
NSArray *querydata;

networkView.hidden = TRUE;
[loadstoresconnection release];
if (storesDataLoc!=nil) {
    [storesDataLoc release];
    storesDataLoc = nil;
}
storesDataLoc = [[NSMutableArray alloc] init];
NSString *txt = [[[NSString alloc] initWithData:responseData encoding: NSASCIIStringEncoding] autorelease];
[responseData release];
// put data into variables.
querydata = [txt componentsSeparatedByString:@"<-sl->"];//break up data into data sections: 0 - number of deptsections and names, 1 - list of objects
NSArray *allstoreinfo;
for (i=0; i<[querydata count]; i++) {
    allstoreinfo = [[querydata objectAtIndex:i] componentsSeparatedByString:@"<-as->"];
    [storesDataLoc addObject:[[[NSMutableDictionary alloc] initWithObjectsAndKeys:[allstoreinfo objectAtIndex:0],@"STid",[allstoreinfo objectAtIndex:1],@"STName",[allstoreinfo objectAtIndex:2],@"STAddr",nil] autorelease]];
}
if ([querydata count]>0) {
    [pickerView reload];
    [pickerView selectRow:0 inComponent:0 animated:NO];
    isHome = NO;
}    

}

Im curious as to why I can see the picker being updated just before the crashes. Because this happens when I'm on the road, I'm suspecting it's an accuracy thing, and location manager is sending a second result, causing the crash. Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请恋爱 2025-01-01 11:56:20

看来我想走太多捷径。当用户点击位置按钮时,它会打开 LocationManager,它会根据每个结果设置一个到我的服务器的 NSURLConnection。我被带去在一个类中处理所有这些,但是由于位置管理器将返回多个结果,NSURLConnections 似乎不受控制。从那时起,我已将每个位置管理器结果放入其自己的类中,并且一切正常。因此,选择器没有问题 - 主要是位置管理器和 nsurlconnections 的内存问题。

It appears I was trying to do too much of a shortcut. When the user hit the location button, it would turn on the LocationManager, which with every result would set up an NSURLConnection to my server. I was bring to handle all this in a single class, but with the multiple results the location manager would return, NSURLConnections seemed to be uncontrolled. I have since put each location manager result in its own class and everything is working honky dory. So, no issue with the picker - mainly a memory issue with location manager and nsurlconnections.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文