質問

だから、過去数日間、私は単純なものを実装する方法を理解するのに苦労してきました mkmapview プロセスでアプリケーションをクラッシュさせることなく、いくつかのカスタム注釈を使用して。残念ながら、私は自分が間違っていることを判断することができず、その過程でますますイライラしています。

私が達成しようとしていることは比較的単純でなければなりません。私はそれに関連する場所を備えた新しいオブジェクトを作成しようとしています。これを行うには、オブジェクトを作成するためのビューコントローラーがあります。ユーザーが望む場合はいつでもビューコントローラーからキャンセルできるようにしたいのですが、オブジェクトを保存するには、最初に場所と名前を提供する必要があります。名前はaで撮影されます 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

customannotation.m

@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

そして、最後になりましたが、私の新しいオブジェクトビューコントローラーの関連部分:

newObjectViewController.M

@implementation NewObjectViewController

@synthesize managedObjectContext;

@synthesize object;

@synthesize objectMapView;

#pragma mark
#pragma mark -
#pragma mark Initialization

-(id) initWithManagedObjectContext:(NSManagedObjectContext*)context{
 self = [super init];
 if (self != nil) {

  [self setManagedObjectContext:context]; 

  Object *newObject = [NSEntityDescription insertNewObjectForEntityForName:@"Object" inManagedObjectContext:self.managedObjectContext];
  self.object = [newObject retain];

 }
 return self;
}


#pragma mark
#pragma mark -
#pragma mark Memory Management

-(void) dealloc {

    [object release], object=nil

 objectMapView.delegate = nil;
 [objectMapView release], objectMapView = nil;
 [super dealloc];
}

#pragma mark 
#pragma mark -
#pragma mark Enable/Disable Button and Textfield States

-(IBAction) updateSaveButtonState{

 if([objectNameTextField.text isEmptyOrWhitespace])
 {
  [saveButton setEnabled:NO];
 }
 else {
  [saveButton setEnabled:YES];
 }
}

#pragma mark
#pragma mark -
#pragma mark UITextField Delegate - Optional Method Implementations

- (void)textFieldDidEndEditing:(UITextField *)textField{ 

 [textField resignFirstResponder];

 if([textField isEqual:objectNameTextField])
 {
  if(![objectNameTextField.text isEmptyOrWhitespace])
  {
   [object setName:objectNameTextField.text];
  }
  else {
   [object setName:nil];
  }
 }
}

- (void)textFieldDidChange:(NSNotification*)aNotification{
 [self updateSaveButtonState];
}

#pragma mark
#pragma mark -
#pragma mark Core Data Persistance Management Procedures

- (IBAction)save {

 if([objectMapView annotations].count != 0)
 {
  NSLog(@"Cleaning up annotations");
  [objectMapView removeAnnotations:[objectMapView annotations]];
 }

 NSError *error = nil;

 //Double Check that all Object Information is Updated Before Saving
 [self textFieldDidEndEditing:NameTextField];

 if (![managedObjectContext save:&error]) {
  // Handle error
  exit(-1);  // Fail
 }  

 objectMapView.delegate = nil;

 [self.delegate newObjectViewController:self didAddObject:object];
}
- (IBAction)cancel {
 [managedObjectContext deleteObject:object];

 if([objectMapView annotations].count != 0)
 {
  NSLog(@"Trying to clean up %d annotations",[objectMapView annotations].count);
  [objectMapView removeAnnotations:[objectMapView annotations]];
 }

 NSError *error = nil;
 if (![managedObjectContext save:&error]) {
  // Handle error
  exit(-1);  // Fail
 }  

 objectMapView.delegate = nil;

 [self.delegate newObjectViewController:self didAddObject:nil];
}


#pragma mark
#pragma mark -
#pragma mark Location Notification Observer Management

-(void) addLocationObserversAndStartUpdatingLocation{ 
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(locationDeniedNotification) name:@"LOCATION_DENIED_NOTIFICATION" object:nil];
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(newLocationNotification) name:@"NEW_LOCATION_NOTIFICATION" object:nil];
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(locationErrorNotification) name:@"LOCATION_ERROR_NOTIFICATION" object:nil];

 [[MyCLController sharedInstance].locationManager startUpdatingLocation]; 
}
-(void) removeLocationObserversAndStopUpdatingLocation{
 [[NSNotificationCenter defaultCenter] removeObserver:self name:@"LOCATION_DENIED_NOTIFICATION" object:nil];
 [[NSNotificationCenter defaultCenter] removeObserver:self name:@"NEW_LOCATION_NOTIFICATION" object:nil];
 [[NSNotificationCenter defaultCenter] removeObserver:self name:@"LOCATION_ERROR_NOTIFICATION" object:nil];

 [[MyCLController sharedInstance].locationManager stopUpdatingLocation];
}

#pragma mark
#pragma mark -
#pragma mark Location Notification Callback Procedures

-(void) newLocationNotification{  
 if(([[MyCLController sharedInstance] locationManager].location != NULL) && ([[MyCLController sharedInstance] locationManager].location != nil))
 {
  [self removeLocationObserversAndStopUpdatingLocation];

  // Add annotation to map 
  CustomMapAnnotation *annotation = [[CustomMapAnnotation alloc] initWithCoordinate:[[MyCLController sharedInstance] locationManager].location.coordinate title:@"Mark Location With Pin"]; 

  [self.objectMapView addAnnotation:annotation];
  [self.objectMapView selectAnnotation:annotation animated:YES];
  [annotation release];
 }
}
-(void) locationErrorNotification{
 [self removeLocationObserversAndStopUpdatingLocation];
}
-(void) locationDeniedNotification{ 
 [self locationErrorNotification];
}


#pragma mark
#pragma mark -
#pragma mark Location Update Procedures

-(IBAction) updateLocationWithPlacemark:(MKPlacemark*)placemark{

 NSDictionary *addressDictionary = [[placemark addressDictionary] retain];
 CLLocationCoordinate2D coordinate = [placemark coordinate];

 //Update Latitude
 [(GeoTag*)[(Location*)[object location] geoTag] setLatitude:[NSNumber numberWithDouble:coordinate.latitude]];

 //Update Longitude
 [(GeoTag*)[(Location*)[object location] geoTag] setLongitude:[NSNumber numberWithDouble:coordinate.longitude]];

 //Update Country
 [object setCountry:[addressDictionary objectForKey:@"CountryCode"]];

 //Update City
 [object setCity:[addressDictionary objectForKey:@"City"]];

 //Update State/Province Initials
 [object setStateOrProvince:[addressDictionary objectForKey:@"State"]];

 //Update ZipCode/PostalCode
 [object setZipCodeOrPostalCode:[addressDictionary objectForKey:@"ZIP"]];

 [addressDictionary release]; 
}

#pragma mark
#pragma mark -
#pragma mark Notification Observers

-(void) addObservers{
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChange:) name:@"UITextFieldTextDidChangeNotification" object:nil];
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(annotationCalloutInfoDidChange:) name:@"MKAnnotationCalloutInfoDidChangeNotification" object:nil];

}
-(void) removeObservers{
 [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UITextFieldTextDidChangeNotification" object:nil];
 [[NSNotificationCenter defaultCenter] removeObserver:self name:@"MKAnnotationCalloutInfoDidChangeNotification" object:nil];

}

#pragma mark
#pragma mark -
#pragma mark Custom Annotation Update Notification Handler

-(void) annotationCalloutInfoDidChange:(NSNotification*)aNotification
{
 CustomAnnotation *annotation = (CustomAnnotation*)[aNotification object];
 [self updateLocationWithPlacemark:[annotation placemark]];

 [self updateSaveButtonState];
}

#pragma mark
#pragma mark -
#pragma mark MKMapViewDelegate Optional Implementations

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {

 if (annotation == mapView.userLocation) {
  return nil;
 }

 CustomAnnotationView *annotationView = (CustomAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"CustomAnnotation"];
 if (annotationView == nil) {
  annotationView = [[[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"CustomAnnotation"] autorelease];
 }

 return annotationView;
}
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{}

#pragma mark
#pragma mark -
#pragma mark View LifeCycle

-(void) viewDidLoad{

    [super viewDidLoad];

 [self addObservers];

 [self addLocationObserversAndStartUpdatingLocation];
}



@end

さらに、ここにクラッシュログがあります:

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   libobjc.A.dylib                 0x00003ec0 objc_msgSend + 24
1   UIKit                           0x0005c8b0 -[UIImageView stopAnimating] + 76
2   UIKit                           0x0005c808 -[UIImageView dealloc] + 20

uiimageviewをリリースした後、[uiimageview stopanimating]に電話してみてください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top