placemark.postalCode deallocated after reloading the ViewController
I have a very strange problem (well, for me) and I'm running crazy! I have a View controller (X) subclass in which I need to know the postalCode (and other informations) about the current user position. In this view I can go back; when I reload X, sometimes I obtain this error: * -[CFString isEqual:]: message sent to deallocated instance 0x6660660
the problem is generated from placemark.postalCode, and I don't understand where or when placemark.postalCode is deallocated.
This is the code of my view controller:
- (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 {
}
This is the code I use to load the view controller:
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];
These are some lines from output:
2011-09-14 19:01:21.097 eyesOnCity[1390:707] reverse geocoder 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 retain count 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] Cap: 12060
2011-09-14 19:01:21.110 eyesOnCity[1390:707] City: 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] reports num: 7
2011-09-14 19:01:25.610 eyesOnCity[1390:707] location found
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 retain count 2
2011-09-14 19:01:25.626 eyesOnCity[1390:707] Report cell dealloc
2011-09-14 19:01:25.636 eyesOnCity[1390:707] Report cell dealloc
2011-09-14 19:01:25.648 eyesOnCity[1390:707] Report cell dealloc
2011-09-14 19:01:25.663 eyesOnCity[1390:707] Report cell 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] reports num: 0
2011-09-14 19:01:28.649 eyesOnCity[1390:707] reverseGeocoder retain 2
2011-09-14 19:01:28.662 eyesOnCity[1390:707] reverse geocoder 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:]: message sent to deallocated instance 0x6660660
Notice the address 0x6660660: same address after reloading the view controller
Any idea?
My question is: how is possible that placemark.postalCode is deallocated if in didFindPlacemark the placemark object is what I receive from the reverseGeocoder object (that is a new object every time I load the view controller)? Really I don't understand what it's wrong with my code! And it seems the memory management is good!
NSLog(@"reverseGeo prima city retain count %d", [city retainCount]);
Please don't do this. Don't use retainCount
. Don't rely on retainCount
. Don't go near retainCount
.
retainCount
does not do what you think it does. Here's Apple's documentation on it (emphasis mine):
This method is typically of no value in debugging memory management issues. Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method
The best thing in the world would be more Apple to deprecate it. It has led to many, many problems - just look at these questions:
- Why has NSNumber such strange retainCounts?
- Objective C NSString* property retain count oddity
...you have people with substantial rep here (in one case, 78k) saying that retainCount
is worthless. Ignore people who say it is useful. It isn't. Doubtless somebody will post a comment to this saying that actually, retainCount is perfectly fine to use. They are wrong. Apple's documentation says not to use it for debugging. A lot of smart people here say not to use it for debugging. It is a bad idea to use it.
The best way to debug memory issues where you're overreleasing (presumably what's happening here) is to make sure you're following the memory management rules. This doesn't particularly help you with your actual problem, although having glanced through the code you posted I'm not sure the problem is immediately apparent (although it's also not the full code of your view controller).
Apple provide a lot of useful tools for debugging memory issues, including build and analyze (clang), and object alloc instruments. Better to use them than retainCount
.
I am not sure about your issue reason but you should use "isEqualToString" for string comparisons rather than "isEqual".
精彩评论