複数のレストランのリストとともにユーザーを地図上に表示するアプリを作成しています。ユーザーがピンをタップすると、注釈からの座標が保存され、ユーザーと比較されて異なることが確認されます。それらが異なると判断されると、ビジネスの座標とユーザーの座標をGoogleに送信して道順をリクエストします。コードは正常に機能していますが、そのためには、メモリリークを引き起こす方法でいくつかの変数を宣言する必要がありました。私はコードをクリーンアップして、どこでエラーが発生したか、そしてこれを適切に処理する方法を学びたいと思っています。
以下は、タップされた注釈から座標を取得するための私のコードです。selectedAnnotationを初期化し、そのメモリを次のように割り当てようとするviewDidLoad
とselectedAnnotation = [[MapLocation alloc] init];
、メモリリークとして表示されます。参考までselectedAnnotation
に、MapLocation(MKAnnotationに準拠)変数があり、プロパティとして(nonatomic、retain)および@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に表示するユーザーの場所のアドレスと座標を抽出します。情報にアクセスするために必要なすべての配列と辞書を作成しましたが、それらにメモリを割り当て、それらの値を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;
}
}
ありとあらゆるヘルプ/提案/アドバイスをありがとう。私はそれをかなりよく理解していると思ったので、私が間違っていることの要点を本当に理解したいと思います。