我正在制作一个应用程序,在地图上显示用户以及多个餐厅列表。当用户点击一个图钉时,它会存储注释中的坐标,并将它们与用户进行比较,以确保它们不同。一旦确定它们不同,它就会将商家的坐标和用户的坐标一起发送给 Google 以请求方向。代码工作正常,但为了做到这一点,我必须以导致内存泄漏的方式声明一些变量。我希望清理代码并了解我出错的地方以及应该处理的正确方法。
所以下面是我从被点击的注释中获取坐标的代码。如果我尝试初始化 selectedAnnotation 并viewDidLoad
通过 putselectedAnnotation = [[MapLocation alloc] init];
然后分配它的内存,它仍然显示为内存泄漏。作为参考,selectedAnnotation
是一个 MapLocation(符合 MKAnnotation)变量,作为一个属性,我拥有它(非原子,保留)和@synthesize(d)。
我以为只要在内存中分配,只要在viewDidUnload中将其值设置为nil并在dealloc中释放,就应该没有内存问题。我错过了什么?下面是我在 viewDidLoad 中为 selectedAnnotation 分配内存时内存泄漏的屏幕截图以及下面提供的代码。如果我已经分配了内存,并检查变量是否存在,为什么还要为变量分配内存?这发生在我点击的任何餐厅 pin 上,但显然不是在用户的 pin 上,因为在这种情况下我有释放它的代码。
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
//NSLog(@"Selected annotation view");
// if we don't have the place holder already allocated
// lazy load the MapLocation placeholder variable
if(!selectedAnnotation)
{
selectedAnnotation = [[MapLocation alloc] init];
}
// save the annotation clicked
selectedAnnotation = view.annotation;
// if the annotation selected was is the same as the user's location
if((selectedAnnotation.coordinate.latitude == savedUserLocation.coordinate.latitude) && (selectedAnnotation.coordinate.longitude == savedUserLocation.coordinate.longitude))
{
// set it to nil and release it
selectedAnnotation = nil;
[selectedAnnotation release];
}
}
我在使用以下方法时遇到了类似的内存问题。我从 Google 引入 JSON 数据,以提取用户位置的地址和坐标以显示在 AnnotationView 中。我创建了所有必要的数组和字典来访问信息,但是一旦我为它们分配内存并将它们的值分配给savedUserLocation,如果我尝试释放说NSDictionary变量userLocation,即使作为此方法中的最后一行代码,应用程序因"[CFDictionary release]: message sent to deallocated instance 0x83ccb60"
. 我很确定这是因为我savedUserLocation
通过指针设置值,一旦内存被释放,信息就不再存在,那么将内存分配/释放到我可以访问信息的位置的正确方法是什么,不会导致内存泄漏?我也尝试过使用autorelease
,但同样的问题仍然存在。
这是放置用户密码的代码。
- (void)fetchedData:(NSData *)responseData
{
//parse out the json data
NSError *error;
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSArray *results = [json objectForKey:@"results"]; //2
NSUInteger counter = [results count];
NSDictionary *userLocation = [[NSDictionary alloc] init];
//NSString *address = [[NSString alloc] init];
for(NSUInteger i=0; i < counter; i++)
{
userLocation = [results objectAtIndex:i];
// 2) Get the funded amount and loan amount
NSString *address = [[NSString alloc] initWithString:[userLocation objectForKey:@"formatted_address"]];
NSArray *types = [userLocation objectForKey:@"types"];
NSDictionary *geometry = [userLocation objectForKey:@"geometry"];
NSDictionary *location = [geometry objectForKey:@"location"];
float lat = [[location objectForKey:@"lat"] floatValue];
float lon = [[location objectForKey:@"lng"] floatValue];
CLLocationCoordinate2D newCoordinates;
newCoordinates.latitude = lat;
newCoordinates.longitude = lon;
// count how many types there are
NSUInteger numberOfTypes = [types count];
NSString *type = [[NSString alloc] init];
for(NSUInteger j=0; j < numberOfTypes; j++)
{
type = [types objectAtIndex:j];
if([type rangeOfString:@"street_address" options:NSCaseInsensitiveSearch].location != NSNotFound)
{
NSLog(@"%@", address);
if(!savedUserLocation)
{
savedUserLocation = [[MapLocation alloc] init];
}
[savedUserLocation setTitle:@"You are here!"];
[savedUserLocation setSubtitle:address];
[savedUserLocation setCoordinate:newCoordinates];
}
}
}
// determine which location is closest to the user by calling this function
MapLocation *closestLocation = [self determineClosestLocationToUser:allLocations locationOfUser:savedUserLocation];
// send in the user location and the closest store to them to determine appropriate zoom level and
// to center the map between the two
[self determineMapCenterAndZoomLevelFromUser:savedUserLocation andClosestLocation:closestLocation];
if(!pinDropped)
{
// add the annotation to the map and then release it
[mapView addAnnotation:savedUserLocation];
pinDropped = true;
}
}
感谢您提供任何和所有帮助/建议/建议。我真的很想了解我做错了什么的具体细节,因为我认为我对它有相当不错的把握。