지도에 사용자를 표시하는 앱을 여러 레스토랑 목록과 함께 만들고 있습니다. 사용자가 핀을 탭하면 주석의 좌표를 저장하고 사용자와 비교하여 좌표가 다른 지 확인합니다. 서로 다르다고 판단되면 사용자 좌표와 함께 비즈니스 좌표를 Google에 전송하여 길 찾기를 요청합니다. 이 코드는 정상적으로 작동하지만 그렇게하기 위해 메모리 누수의 원인이되는 몇 가지 변수를 선언해야했습니다. 나는 코드를 깨끗이하고 내가 실수 한 곳과 이것이 처리되어야하는 적절한 방법을 배우기를 바라고있다.MKAnnotation 및 NSString 메모리 누수 문제에 대한 조언
다음은 탭한 주석에서 좌표를 가져 오는 코드입니다. selectedAnnotation을 초기화하고 selectedAnnotation = [[MapLocation alloc] init];
을 입력하여 viewDidLoad
에 메모리를 할당하려고하면 여전히 메모리 누수로 표시됩니다. 그리고 참조 용으로 selectedAnnotation
은 MapLocation (MKAnnotation을 준수) 변수이며 속성으로 (비 원자형, 보유 형) 및 @synthesize (d)가 있습니다.
나는 viewDidUnload에서 값을 nil로 설정하고 dealloc에서 해제 했으므로 아무런 메모리 문제가 없어야 만 메모리에 할당했다. 내가 뭘 놓치고 있니? 다음은 아래에 제공된 코드와 함께 viewDidLoad의 selectedAnnotation에 대한 메모리를 할당 할 때 내 메모리 누수에 대한 스크린 샷입니다. 이미 메모리를 할당하고 변수가 존재하는지 확인하면 왜 변수에 메모리를 다시 할당합니까? 이것은 내가 클릭하는 레스토랑 핀에서 발생하지만, 분명히 사용자의 핀에있는 것은 아닙니다.이 경우에 코드를 릴리스 할 것이기 때문입니다.
-(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에 표시 할 사용자 위치의 주소와 좌표를 추출합니다. 정보에 액세스하기 위해 필요한 모든 배열과 사전을 만들었지 만, 일단이 메서드의 코드 마지막 줄인 NSDictionary 변수 userLocation을 해제하려고 시도하면 해당 변수에 대한 메모리를 할당하고 해당 값을 savedUserLocation에 할당합니다.
"[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;
}
}
모든 도움/제안/조언에 감사드립니다. 저는 제가 잘못하고있는 것에 대한 견해와 견해를 이해하고 싶습니다. 제가 꽤 괜찮은 생각을하고 있다고 생각했습니다.
selectedAnnotation = nil;
[selectedAnnotation release];
이 당신이 selectedAnnotation
nil
에와 다음 그것에 release
를 호출 설정되어 있기 때문에 메모리 누수가 발생합니다 : didSelectAnnotationView
에서
실제로 selectedAnnotation의 경우 nil/release의 순서를 수정 한 후에도 문제가 계속 발생합니다. 그 이유는 alloc (포인터를 다시 할당 한 후)과 userLocation의 이유가 동일하기 때문입니다. 따라서 selectedAnnotation에 대해 ivar을 선언하고/init/release를 할당하지 마십시오 (또는 더 좋게는지도보기의 selectedAnnotations 속성 만 사용하십시오). – Anna
'self.mapView.selectedAnnotation' 속성에 대한 머리를 주셔서 감사합니다. 내 모든 속성을 완벽하게 대체했습니다. 감사하게 생각합니다. 문자열에 대한 모든'alloc' 호출까지, 나는 그것들 중 2 개를 제거 할 수 있었지만, NSString * address = [[NSString alloc] initWithString : [userLocation objectForKey : @ "formatted_address"]]; ''MKAnnotations' 부제에 값을 보내기 때문에 추측하고 있습니다. 만약 내가'alloc '하지 않거나 for 루프 이후에'release' 시도를하면, 충돌이 발생합니다 :'- [CFString stringByStandardizingWhitespace] : 해제 된 인스턴스에 메시지 전송 됨' –
savedUserLocation과 함께 메모리 관리 문제가 있음을 나타냅니다. 또한 MapLocation의 자막 속성이'copy' ('assign' 또는'retain'이 아닌)로 정의되어 있는지 확인하십시오. – Anna