重新加载ViewController后取消分配placemark.postalCode

时间:2011-09-15 08:46:35

标签: iphone objective-c ios

我有一个非常奇怪的问题(好吧,对我而言)而且我疯了! 我有一个View控制器(X)子类,我需要知道有关当前用户位置的postalCode(和其他信息)。 在这种观点中,我可以回去;当我重新加载X时,有时我会收到此错误: * - [CFString isEqual:]:发送到解除分配的实例0x6660660的消息

问题是从placemark.postalCode生成的,我不明白placemark.postalCode在哪里或何时被解除分配。

这是我的视图控制器的代码:

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{

self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
  //  reportsToUpdate = NO;
 //   locationValFound = NO;
    NSLog(@"init city retain count %d", [city retainCount]);
}
return self;

}





 - (void)dealloc
{
    if(locationValFound)
        NSLog(@"location found");
    else NSLog(@"location not found"); 
    EyesOnCityAppDelegate *appDelegate = (EyesOnCityAppDelegate *)[[UIApplication sharedApplication] delegate];
    [appDelegate.downloadQueue  cancelAllOperations];
    [request clearDelegatesAndCancel];
    [request release];
    [reportsTableView release];
    mapView.delegate = nil;
    [mapView release];
    mapView = nil;
    if (reverseGeocoder) {
        NSLog(@"reverseGeo dealloc");
        [reverseGeocoder cancel];
    }
    reverseGeocoder.delegate = nil;
    NSLog(@"Reverse geo delegate nil");
    [reverseGeocoder release];
    reverseGeocoder = nil;
    [reportsArray removeAllObjects];
    [reportsArray release];
    [reportImagesArray removeAllObjects];
    [reportImagesArray release];

    [waitMessageLabel release];
    [waitAI release];
    [genericVal release];
    [viewType release];
    [idType release];
    [typeName release];
    [cap release];
    NSLog(@"dealloc retain count %d", [city retainCount]);
    [city release];

    [super dealloc];
}



 - (void) reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {
    //NSLog(@"placemark %@", placemark);
    NSLog(@"reverse geocoder placemark.postalcode %p", placemark.postalCode);
    NSLog(@"fuori cap address %p", &cap);
    if (placemark && ![placemark.postalCode isEqual:@""] && ![placemark.locality isEqual:@""] && !locationValFound) {
        locationValFound = YES;
        cap = placemark.postalCode;
        NSLog(@"dentro cap address %p", &cap);
        NSLog(@"reverseGeo prima city retain count %d", [city retainCount]);
        city = placemark.locality;
        NSLog(@"reverseGeo dopo city retain count %d", [city retainCount]);

        NSLog(@"Cap: %@", cap);
        NSLog(@"City: %@", city);

        mapView.delegate = nil;
        [mapView release];
        mapView = nil;
        [reverseGeocoder placemark]; 

        [self downloadReports];        
    }
}



     - (void) mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {

    if (!locationValFound && ![reverseGeocoder isQuerying]) {
        reverseGeocoder = [[MKReverseGeocoder alloc] initWithCoordinate:userLocation.coordinate];

        reverseGeocoder.delegate = self;
        [reverseGeocoder start];
        NSLog(@"reverseGeocoder retain %d", [reverseGeocoder retainCount]);
    }
}

    - (void) reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error {

}

这是我用来加载视图控制器的代码:

ReportsViewController *reportsViewController = [[ReportsViewController alloc] initWithNibName:@"ReportsViewController" bundle:nil];

  //  [reportsViewController setReportsToUpdate:NO];
[reportsViewController setTypeName:[[typesArray objectAtIndex:indexPath.row] name]];
[reportsViewController setGenericVal:[[typesArray objectAtIndex:indexPath.row] generic]];
[reportsViewController setViewType:[[typesArray objectAtIndex:indexPath.row] type]];
[reportsViewController setIdType:[[typesArray objectAtIndex:indexPath.row] idType]];

//}     UIBarButtonItem * backButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedStringFromTable(@“BackBtnText”,@“EyesOnCity_localizable”,@“”)style:UIBarButtonItemStylePlain target:nil action:nil];     self.navigationItem.backBarButtonItem = backButton;     [backButton release];

[self.navigationController pushViewController:reportsViewController animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[reportsViewController release];

这些是输出中的一些行:

2011-09-14 19:01:21.097 eyesOnCity [1390:707]反向地理编码器placemark.postalcode 0x6660660

2011-09-14 19:01:21.099 eyesOnCity [1390:707] fuori cap address 0x663f29c

2011-09-14 19:01:21.101 eyesOnCity [1390:707] dentro cap address 0x663f29c

2011-09-14 19:01:21.104 eyesOnCity [1390:707] reverseGeo prima city保留计数0

2011-09-14 19:01:21.106 eyesOnCity [1390:707] reverseGeo dopo city retain count 3

2011-09-14 19:01:21.108 eyesOnCity [1390:707]上限:12060

2011-09-14 19:01:21.110 eyesOnCity [1390:707]城市:Niella Tanaro

2011-09-14 19:01:21.138 eyesOnCity [1390:707] Lista id:

2011-09-14 19:01:21.141 eyesOnCity [1390:707] lang:it_IT

2011-09-14 19:01:22.848 eyesOnCity [1390:707]报告数:7

2011-09-14 19:01:25.610 eyesOnCity [1390:707]找到位置

2011-09-14 19:01:25.614 eyesOnCity [1390:707] reverseGeo dealloc

2011-09-14 19:01:25.616 eyesOnCity [1390:707] Reverse geo delegate nil

2011-09-14 19:01:25.622 eyesOnCity [1390:707] dealloc保留计数2

2011-09-14 19:01:25.626 eyesOnCity [1390:707]报告细胞dealloc

2011-09-14 19:01:25.636 eyesOnCity [1390:707]报告细胞dealloc

2011-09-14 19:01:25.648 eyesOnCity [1390:707]报告细胞dealloc

2011-09-14 19:01:25.663 eyesOnCity [1390:707]报告细胞dealloc

2011-09-14 19:01:28.450 eyesOnCity [1390:707] init city retain count 0

2011-09-14 19:01:28.553 eyesOnCity [1390:707]报告数:0

2011-09-14 19:01:28.649 eyesOnCity [1390:707] reverseGeocoder保留2

2011-09-14 19:01:28.662 eyesOnCity [1390:707]反向地理编码器placemark.postalcode 0x6660660

2011-09-14 19:01:28.664 eyesOnCity [1390:707] fuori cap address 0x668d9bc

2011-09-14 19:01:28.666 eyesOnCity [1390:707] * - [CFString isEqual:]:发送到解除分配的实例的消息0x6660660

注意地址0x6660660:重新加载视图控制器后的相同地址

有什么想法吗?


我的问题是:如果在didFindPlacemark中地标对象是我从reverseGeocoder对象(每次加载视图控制器时都是一个新对象)的地方对象,那么placemark.postalCode是如何被释放的? 真的,我不明白我的代码有什么问题!而且内存管理似乎很好!

2 个答案:

答案 0 :(得分:1)

  

NSLog(@"reverseGeo prima city retain count %d", [city retainCount]);

请不要这样做。不要使用retainCount。不要依赖retainCount。不要靠近retainCount

retainCount没有按照您的想法行事。这是Apple关于它的文档(强调我的):

  

此方法在调试内存管理问题时通常没有价值。因为任何数量的框架对象可能保留了一个对象以保存对它的引用,而同时自动释放池可能在对象上持有任意数量的延迟版本,所以非常不可能你可以从这个方法中获得有用的信息

世界上最好的事情是苹果公司会弃用它。它导致了许多问题 - 只看这些问题:

...你们这里有大量代表的人(在一个案例中,78k)说retainCount毫无价值。忽略那些说它有用的人。事实并非如此。毫无疑问,有人会对这个说法发表评论,实际上,retainCount是完全可以使用的。他们错了。 Apple的文档说不要用它来进行调试。这里有很多聪明的人说不要用它来调试。使用它是个坏主意。

调试内存问题的最好方法就是确保你遵循memory management rules,这是你过度释放的地方(可能是这里发生的事情)。这对您的实际问题并没有特别的帮助,虽然浏览了您发布的代码我不确定问题是否立即显现(尽管它也不是您的视图控制器的完整代码)。

Apple为调试内存问题提供了许多有用的工具,包括构建和分析(clang)以及对象分配工具。比retainCount更好地使用它们。

答案 1 :(得分:0)

我不确定你的问题原因,但你应该使用“isEqualToString”进行字符串比较而不是“isEqual”。