2009-11-07 5 views
1

지난 며칠 동안 간단한 애프터 마노 지에 MKMapView을 구현하는 방법을 이해하는 데 어려움을 겪었습니다. 불행하게도 내가 뭘 잘못하고 있는지를 판단 할 수 없었고 그 과정에서 점점 더 좌절하게되었습니다.iPhone에서 MKMapKit 관련 크래시를 피하는 방법

내가 성취하려는 것은 상대적으로 간단해야합니다. 새로운 객체를 만들려고합니다. 위치는 연관된 객체입니다. 이렇게하려면 개체를 만들기위한보기 컨트롤러가 있습니다. 사용자가 원하는 경우 언제든지보기 컨트롤러를 취소 할 수 있기를 원하지만 개체를 ​​저장하려면 먼저 위치와 이름을 제공해야합니다. 이름은 UITextField을 통해 가져 오며 위치는 MKMapView를 통해 가져옵니다.

그래서 다음과 같이됩니다. 새 객체보기 컨트롤러를 열 때마다 위치 및 기타 등등이 업데이트됩니다. 취소를 클릭하면 충돌이 발생합니다. 문제를 단순화하기 위해 위치를 업데이트하고 주석 핀을 이동하는 코드를 제거 했으므로 아래에서 볼 수 없습니다.

다음은 충돌 후 발생한 스택 추적 예제 외에도 사용중인 코드 중 일부입니다. 당신이 제공 할 수있는 어떤 도움도 크게 감사 할 것입니다. 감사! 충돌

#1 0x30c4c8b8 in -[UIImageView stopAnimating] 
#2 0x30c4c810 in -[UIImageView dealloc] 
#3 0x32d86640 in -[NSObject release] 
#4 0x32d198ac in -[MKAnnotationView dealloc] 
#5 0x32d86640 in -[NSObject release] 
#6 0x30bfab34 in -[UIView(Hierarchy) removeFromSuperview] 
#7 0x30c4ca24 in -[UIView dealloc] 
#8 0x32ce881c in -[MKOverlayView dealloc] 
#9 0x32d86640 in -[NSObject release] 
#10 0x30bfab34 in -[UIView(Hierarchy) removeFromSuperview] 
#11 0x30c4ca24 in -[UIView dealloc] 
#12 0x30cbb878 in -[UIScrollView dealloc] 
#13 0x32d179c4 in -[MKScrollView dealloc] 
#14 0x32d86640 in -[NSObject release] 
#15 0x30bfab34 in -[UIView(Hierarchy) removeFromSuperview] 
#16 0x30cbb4a8 in -[UIScrollView removeFromSuperview] 
#17 0x30c4ca24 in -[UIView dealloc] 
#18 0x32d86640 in -[NSObject release] 
#19 0x30bfab34 in -[UIView(Hierarchy) removeFromSuperview] 
#20 0x30c4ca24 in -[UIView dealloc] 
#21 0x32cc579c in -[MKMapView dealloc] 
#22 0x32d86640 in -[NSObject release] 
#23 0x30bfab34 in -[UIView(Hierarchy) removeFromSuperview] 
#24 0x30c4ca24 in -[UIView dealloc] 
#25 0x32d86640 in -[NSObject release] 
#26 0x30bfab34 in -[UIView(Hierarchy) removeFromSuperview] 
#27 0x30c4ca24 in -[UIView dealloc] 
#28 0x32d86640 in -[NSObject release] 
#29 0x30bfab34 in -[UIView(Hierarchy) removeFromSuperview] 
#30 0x30c4ca24 in -[UIView dealloc] 
#31 0x32d86640 in -[NSObject release] 
#32 0x30bfab34 in -[UIView(Hierarchy) removeFromSuperview] 
#33 0x30c4ca24 in -[UIView dealloc] 
#34 0x32d86640 in -[NSObject release] 
#35 0x33f70996 in NSPopAutoreleasePool 
#36 0x33e99104 in run_animation_callbacks 
#37 0x33e98e6c in CA::timer_callback 
#38 0x32da44c2 in CFRunLoopRunSpecific 
#39 0x32da3c1e in CFRunLoopRunInMode 
#40 0x31bb9374 in GSEventRunModal 
#41 0x30bf3c30 in -[UIApplication _run] 
#42 0x30bf2230 in UIApplicationMain 
#43 0x00002450 in main at main.m:14 

CustomAnnotation.h

스택 추적 : 난 당신이 내 코드를 표시하기 전에

, 여기에 내가 끝낼 스택 추적입니다

@interface CustomAnnotation : NSObject <MKAnnotation, 
      MKReverseGeocoderDelegate> 
{ 
@private 
MKReverseGeocoder* _reverseGeocoder; 
MKPlacemark* _placemark; 

@public 
CLLocationCoordinate2D _coordinate; 
NSString*  _title; 
} 

//Note: Property for CLLocationCoordinate2D coordinate is declared in MKAnnotation 
@property (nonatomic, retain) NSString*  title; 
@property (nonatomic, retain) MKPlacemark* placemark; 

-(id) initWithCoordinate:(CLLocationCoordinate2D)coordinate 
     title:(NSString*)title; 

-(void) setCoordinate:(CLLocationCoordinate2D)coordinate; 

@end 

맞춤 설명.

@implementation CustomAnnotation 

@synthesize coordinate  = _coordinate; // property declared in MKAnnotation.h 
@synthesize title = _title; 
@synthesize placemark = _placemark; 

-(id) initWithCoordinate:(CLLocationCoordinate2D)coordinate 
     title:(NSString*)title 
{ 
if(self = [super init]) 
{ 
    _title  = [title retain]; 
    [self setCoordinate:coordinate]; 
    _placemark = nil; 
} 
return self; 
} 

#pragma mark - 
#pragma mark MKAnnotationView Notification 

- (void)notifyCalloutInfo:(MKPlacemark *)newPlacemark { 
[self willChangeValueForKey:@"subtitle"]; // Workaround for SDK 3.0, otherwise callout info won't update. 
self.placemark = newPlacemark; 
[self didChangeValueForKey:@"subtitle"]; // Workaround for SDK 3.0, otherwise callout info won't update. 

[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"MKAnnotationCalloutInfoDidChangeNotification" object:self]]; 
} 

#pragma mark 
#pragma mark - 
#pragma mark Reverse Geocoder Reset Procedure 

- (void)resetReverseGeocoder 
{ 
if(_reverseGeocoder != nil) 
{ 
    //If the reverse geocoder already exists, check to make sure it isn't querying. Cancel query if it is. 
    if([_reverseGeocoder isQuerying]) 
    { 
    [_reverseGeocoder cancel]; 
    } 

    //Before releasing the reverse geocoder, set it's delegate to nil just to be safe 
    [_reverseGeocoder setDelegate:nil]; 

    //Release the current reverse geocoder 
    [_reverseGeocoder release]; 
    _reverseGeocoder = nil; 
} 
} 

#pragma mark 
#pragma mark - 
#pragma mark Set Coordinate Procedure 

- (void)setCoordinate:(CLLocationCoordinate2D)coordinate { 
_coordinate = coordinate; 

//We only want to be reverse geocoding one location at a time, so make sure we've reset the reverse geocoder before starting 
[self resetReverseGeocoder]; 

//Create a new reverse geocoder to find the location for the given coordinate, and start the query 
_reverseGeocoder = [[MKReverseGeocoder alloc] initWithCoordinate:_coordinate]; 
[_reverseGeocoder setDelegate:self]; 
[_reverseGeocoder start]; 
} 

#pragma mark 
#pragma mark - 
#pragma mark MKAnnotation Delegate Procedure Implementations 

- (NSString *)subtitle 
{ 
NSString* subtitle = nil; 

if (_placemark) 
{ 
    subtitle = [NSString stringWithString:[[_placemark.addressDictionary objectForKey:@"FormattedAddressLines"] objectAtIndex:1]]; 
    } 
    else 
    { 
    subtitle = [NSString stringWithFormat:@"%lf, %lf", _coordinate.latitude, _coordinate.longitude]; 
    } 

return subtitle; 
} 

#pragma mark - 
#pragma mark MKReverseGeocoderDelegate methods 

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)newPlacemark { 

if(geocoder != _reverseGeocoder) 
{ 
    NSLog(@"WARNING:::: MORE THAN ONE REVERSE GEOCODER!!!"); 
    NSLog(@"_reverseGeocoder = %@",[_reverseGeocoder description]); 
    NSLog(@"geocoder = %@",[geocoder description]); 
} 

[self notifyCalloutInfo:newPlacemark]; 

[self resetReverseGeocoder]; 
} 

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

if(geocoder != _reverseGeocoder) 
{ 
    NSLog(@"WARNING:::: MORE THAN ONE REVERSE GEOCODER!!!"); 
    NSLog(@"_reverseGeocoder = %@",[_reverseGeocoder description]); 
    NSLog(@"geocoder = %@",[geocoder description]); 
} 

[self notifyCalloutInfo:nil]; 

[self resetReverseGeocoder]; 
} 


#pragma mark - 
#pragma mark Memory Management 

- (void)dealloc { 

[self resetReverseGeocoder]; 

[_title release], _title = nil; 
[_placemark release], _placemark = nil; 

[super dealloc]; 
} 

@end 

둘째, 나는 사용자 정의 주석보기

CustomAnnotationView.h

@interface CustomAnnotationView : MKAnnotationView { 

} 

@end 

CustomAnnotationView.m

@implementation CustomAnnotationView 

- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier 
{ 
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; 

UIGraphicsBeginImageContext(CGSizeMake(30,30)); 

     //Note: [UIImage drawInRect:radius:contentMode:] is a Three20 Procedure 
[[UIImage imageNamed:@"annoationIcon.png"] drawInRect:CGRectMake(0,0,30,30) radius:6.0f contentMode:UIViewContentModeScaleAspectFill]; 

UIImage *iconImage = UIGraphicsGetImageFromCurrentImageContext(); 

//pop the context to get back to the default 
UIGraphicsEndImageContext(); 

UIImageView *leftIconView = [[UIImageView alloc] initWithImage:iconImage]; 
self.leftCalloutAccessoryView = leftIconView; 
[leftIconView release]; 

[iconImage release]; 

return self; 
} 

@end 

을 만들고, 마지막으로 한 , 관련 내 새 개체보기 컨트롤러의 NT 부품 :

Thread 0 Crashed: 
0 libobjc.A.dylib     0x00003ec0 objc_msgSend + 24 
1 UIKit       0x0005c8b0 -[UIImageView stopAnimating] + 76 
2 UIKit       0x0005c808 -[UIImageView dealloc] + 20 
3 CoreFoundation     0x0003963a -[NSObject release] + 28 
4 MapKit       0x0006b8a4 -[MKAnnotationView dealloc] + 80 
5 CoreFoundation     0x0003963a -[NSObject release] + 28 
6 UIKit       0x0000ab2c -[UIView(Hierarchy) removeFromSuperview] + 592 
7 UIKit       0x0005ca1c -[UIView dealloc] + 232 
8 MapKit       0x0003a814 -[MKOverlayView dealloc] + 804 
9 CoreFoundation     0x0003963a -[NSObject release] + 28 
10 UIKit       0x0000ab2c -[UIView(Hierarchy) removeFromSuperview] + 592 
11 UIKit       0x0005ca1c -[UIView dealloc] + 232 
12 UIKit       0x000cb870 -[UIScrollView dealloc] + 284 
13 MapKit       0x000699bc -[MKScrollView dealloc] + 88 
14 CoreFoundation     0x0003963a -[NSObject release] + 28 
15 UIKit       0x0000ab2c -[UIView(Hierarchy) removeFromSuperview] + 592 
16 UIKit       0x000cb4a0 -[UIScrollView removeFromSuperview] + 68 
17 UIKit       0x0005ca1c -[UIView dealloc] + 232 
18 CoreFoundation     0x0003963a -[NSObject release] + 28 
19 UIKit       0x0000ab2c -[UIView(Hierarchy) removeFromSuperview] + 592 
20 UIKit       0x0005ca1c -[UIView dealloc] + 232 
21 MapKit       0x00017794 -[MKMapView dealloc] + 1384 
22 CoreFoundation     0x0003963a -[NSObject release] + 28 
23 UIKit       0x0000ab2c -[UIView(Hierarchy) removeFromSuperview] + 592 
24 UIKit       0x0005ca1c -[UIView dealloc] + 232 
25 CoreFoundation     0x0003963a -[NSObject release] + 28 
26 UIKit       0x0000ab2c -[UIView(Hierarchy) removeFromSuperview] + 592 
27 UIKit       0x0005ca1c -[UIView dealloc] + 232 
28 CoreFoundation     0x0003963a -[NSObject release] + 28 
29 UIKit       0x0000ab2c -[UIView(Hierarchy) removeFromSuperview] + 592 
30 UIKit       0x0005ca1c -[UIView dealloc] + 232 
31 CoreFoundation     0x0003963a -[NSObject release] + 28 
32 UIKit       0x0000ab2c -[UIView(Hierarchy) removeFromSuperview] + 592 
33 UIKit       0x0005ca1c -[UIView dealloc] + 232 
34 CoreFoundation     0x0003963a -[NSObject release] + 28 
35 Foundation      0x00047990 NSPopAutoreleasePool + 238 
36 QuartzCore      0x0001e0fc run_animation_callbacks(double, void*) + 600 
37 QuartzCore      0x0001de64 CA::timer_callback(__CFRunLoopTimer*, void*) + 156 
38 CoreFoundation     0x000574bc CFRunLoopRunSpecific + 2192 
39 CoreFoundation     0x00056c18 CFRunLoopRunInMode + 44 
40 GraphicsServices    0x0000436c GSEventRunModal + 188 
41 UIKit       0x00003c28 -[UIApplication _run] + 552 
42 UIKit       0x00002228 UIApplicationMain + 960 
43 TestApp       0x0000244a main (main.m:14) 
44 TestApp       0x000021d4 start + 44 
+0

빠른 참고 사항 ...어노테이션 뷰를 이동하고 위치를 업데이트하는 코드를 제거했다고 말했을 때 코드를 테스트하기 전에 테스트를 수행 했으므로 나중에 테스트를 수행하지 않으므로 아무 것도 남기지 않고 그냥 취소 할 수 있습니다 보기 w/out 충돌 및 다음 다른 세부 사항에 대해 걱정할 것이다. – TheAggie

답변