2011-09-13 6 views
1

(完全なソースコードが含まれています)狂気私を駆動するEXC_BAD_ACCESSといくつかの助けが必要。
このアプリケーションには、カスタムアノテーションとuserLocationのカスタムビューを表示したいと思います。ロケーションマネージャが見出しを与えたときに、私がuserLocationのカスタムビューを表示したい場合、それを配信できない場合は、デフォルトの青いアニメーションドットが戻ってくるようにしたい。iPhoneは - 私はGoogleマップビューを使用してアプリを持っている

利用可能なプロジェクトとソースコードHERE

さて、ここで2つの問題があります

第一の問題は、本当に悪いONE。小さなアプリで数時間プレイすることができます。しかし、それを起動し、ロード待ち、バックグラウンドに送信、iPhoneをスリープモードにして、1分待って、あなたのiPhoneを起動させ、アプリを起動させる(それを起こす):クラッシュ、EXC_BAD_ACCESS。同じことをiPhoneをスリープモードにしないでください。クラッシュすることはありません。数分、数秒待つことなく、クラッシュすることはありません。 10秒、クラッシュなし、20秒、クラッシュなし、30秒に近い、クラッシュ、おそらくクラッシュ、クラッシュ!

第二の問題(:-)ボーナス)、最初のものとリンクすることができ、それは本当にこの問題の核心ではありません:私は/から青に更新するuserPinLocationを達成するために使用するソリューションピンは本当に悪い副作用を持っているようです:あなたが通りに移動すると、userLocationはマップ上を移動しません。その2番目の問題に対する答えは、クラッシュと直接リンクしていない場合は、コメントではなく答えを使用してください。これは私がその最小で私のアプリを低減してきた、障害のあるコードを見つけるために...私は思う...

問題の核心ではありません。すなわち、次のコード(コメントとしてソースコード内のいくつかのヒント)を与える:

EXC_BAD_ACCESS_TestViewController.h

#import <MapKit/MapKit.h> 

@interface EXC_BAD_ACCESS_TestViewController : UIViewController<CLLocationManagerDelegate> { 

    CLLocationManager* locationMgr; 
    NSMutableArray* customAnnotations; 
    CLLocationDirection userHeading; 
    MKMapView* myMapView; 
} 

@property(nonatomic, retain) CLLocationManager* locationMgr; 
@property(nonatomic, retain) NSMutableArray* customAnnotations; 
@property(nonatomic, assign) CLLocationDirection userHeading; 
@property(nonatomic, retain) IBOutlet MKMapView* myMapView; 

- (void) loadAnnotations; 

@end 

EXC_BAD_ACCESS_TestViewController.m

// On first launch, due to code simplification, the app may crash when asked authorization to use geo hardware. Just kill/relaunch after accepting. 
// Breakpoints on each method entry : EXC_BAD_ACCESS crash without any break-stop 

#import "EXC_BAD_ACCESS_TestViewController.h" 
#import "CustomAnnotation.h" 

@implementation EXC_BAD_ACCESS_TestViewController 

@synthesize locationMgr, customAnnotations, myMapView, userHeading; 

// =========================================================================================================== 
-(id) initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super initWithCoder:aDecoder]; 
    if (!self) return nil; 

    self.userHeading = -1; 

    return self; 
} 

// =========================================================================================================== 
- (void) viewDidLoad 
{ 
    [self loadAnnotations]; 

    self.myMapView.mapType = MKMapTypeStandard; 
    self.myMapView.showsUserLocation = YES; 

    // ----------------------------------------------- 
    // Just comment this sole line : no more crash 
    // ----------------------------------------------- 
    for (CustomAnnotation* pin in self.customAnnotations) [self.myMapView addAnnotation:pin]; 

    // locationManager 
    self.locationMgr = [[CLLocationManager alloc] init]; 
    self.locationMgr.desiredAccuracy = kCLLocationAccuracyBest; 
    self.locationMgr.distanceFilter = 1.0; 
    self.locationMgr.headingFilter = 1.0; 
    self.locationMgr.purpose = @"Some purpose."; 
    self.locationMgr.delegate = self; 
    [self.locationMgr startUpdatingHeading]; 

    [super viewDidLoad]; 
} 

// =========================================================================================================== 
- (void) loadAnnotations 
{ 
    // Code for testing, real code gets the datas using another way of doing, as simple as this one 
    self.customAnnotations = [NSMutableArray array]; 
    double latitude = 45.0; 
    double longitude = -45.0; 

    for (int i=1; i<=400; i++) { 
     CLLocationCoordinate2D pinLocation = CLLocationCoordinate2DMake(latitude, longitude); 
     CustomAnnotation* pin = [[[CustomAnnotation alloc] initWithCoordinate:pinLocation] autorelease];    
     [self.customAnnotations addObject:pin]; 

     latitude += 0.01; 
     longitude += 0.01; 
    } 
} 

// =========================================================================================================== 
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation 
{ 
    MKAnnotationView* pinView = nil; 
    NSString* annotationIdentifier; 
    UIImage* pinImage; 
    BOOL canShowCallout; 

    // User location 
    if ([annotation isKindOfClass:[MKUserLocation class]] && self.userHeading >= 0) { 
     annotationIdentifier = @"UserLocationAnnotation"; 
     pinImage = [UIImage imageNamed:@"custom_userlocation.png"]; 
     canShowCallout = NO; 
    } 
    // Custom Pin 
    else if ([annotation isKindOfClass:[CustomAnnotation class]]) { 
     annotationIdentifier = @"CustomAnnotation"; 
     pinImage = [UIImage imageNamed:@"custom_pin.png"]; 
     canShowCallout = YES; 
    } 
    // Others 
    else { 
     return nil; 
    } 

    pinView = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier]; 

    if (pinView) { 
     pinView.annotation = annotation; 
    } 
    else { 
     pinView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier] autorelease]; 
     if (pinView) { 
      pinView.image = pinImage; 
      pinView.canShowCallout = canShowCallout; 

      if (canShowCallout) { 
       pinView.calloutOffset = CGPointMake(-5, 5); 
       pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; 
      } 
     } 
    } 

    return pinView; 
} 

// ----------------------------------------------- 
// Just comment this method : no more crash 
// ----------------------------------------------- 
// =========================================================================================================== 
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading 
{ 
    if (!self.myMapView) return; 
    if (!self.myMapView.userLocation) return; 

    CLLocationDirection compassHeading_True = newHeading.trueHeading; 
    CLLocationDirection compassHeading_Magnetic = newHeading.magneticHeading; 

    CLLocationDirection heading; 
    if (compassHeading_True == -1)    heading = compassHeading_Magnetic; 
    else if (newHeading.headingAccuracy >= 0) heading = compassHeading_True; 
    else          heading = -1; 

    // If we get/loose the heading, update pin image 
    // I didn't found any other solution to force the user pin to update its display. 
    if ((self.userHeading == -1 || heading == -1) && self.userHeading != heading) { 
     [self.myMapView removeAnnotation:self.myMapView.userLocation]; 
     self.userHeading = heading; 
     [self.myMapView addAnnotation:self.myMapView.userLocation]; 
    } 

    self.userHeading = heading; 

    // ------------------------------------ 
    // Some non bugued code was there 
    // ------------------------------------ 
} 

// =========================================================================================================== 
- (void) dealloc 
{ 
    self.myMapView = nil; 
    self.customAnnotations = nil; 
    self.locationMgr = nil; 

    [super dealloc]; 
} 

@end 

CustomAnnotation.h

#import <MapKit/MapKit.h> 

@interface CustomAnnotation : NSObject<MKAnnotation> { 
    CLLocationCoordinate2D coordinate; 
} 

@property(nonatomic, assign) CLLocationCoordinate2D coordinate; 

- (id)initWithCoordinate:(CLLocationCoordinate2D) c; 
@end 

CustomAnnotation.m

ゾンビを環境変数で有効にしようとすると、それぞれの方法でブレークポイントを試しました(ただし、デバイス上で実行する必要があるため、実際に起動しているかどうかはわかりません)。 ...私はまだ何がうまくいかないのか分からない。

は、あなたがそのEXC_BAD_ACCESSの問題を解決する方法を見ていますか?
2番目の問題の解答は、解を解決できない場合は解答ではなくコメントを使用してください。この問題は、私が見た限り、問題の中心ではありません。

ヒント:私は解決策のいくつかの開始を発見したところ、上記のコードで2件のコメントを入れています。接続されていない2つの場所があり、問題を解決するためにコードの一方または他方から外すことができます。私を狂ってしまうのはORです。

iPhone 4 iOS 4.2で動作します。1

+0

私たちのために小さなアプリケーションを作成して、mediafire.comや他のいくつかのウェブサイトにアップロードして、ここにURLを投稿してもらうことができますか?プロジェクトを作成してコードをコピーしてデバッグするのはあまりにも怠惰です。 – ARC

+0

@Nikita:ok、done、my editを参照してください – Oliver

+1

[self.myMapView removeAnnotation:self.myMapView.userLocation]; //この行はstacktraceからクラッシュする原因となっています。これは私が見たものです。 – ARC

答えて

1
[self.myMapView removeAnnotation:self.myMapView.userLocation]; 

をチェックしてください。

私がexc_bad_accessを見たとき、私はgdbでbtをやった。私はGuard Mallocブレークポイントを追加しました。スタックを見ると、注釈を削除することができました。

+0

「btをgdbにしてください。私はGuard Mallocブレークポイントを追加しました。 ? btとは何ですか?あなたはどのようにGuard malloc bpを設定しましたか? – Oliver

+1

BTはトレースバックです。 XCode - > Goto Run - > Show - > Breakpoints(Alt-Command-B)、リストの一番下までスクロールしてシンボルを追加します。malloc_error_break – ARC

+0

これを行いましたが、ブレークポイントが定義されていない場合と全く同じです。さらなる読者のためにあなたの答えにいくつかの詳細(スクリーンショット)を入れてください。定義したBPと、エラーを示したスタックトレース。お願いします ? – Oliver

0

didReceiveMemoryWarningというメソッドをオーバーライドして、表示コントローラ.mファイルで試すことができます。

時には、アプリケーションの実行中にデバイスのメモリが低下し、IOSがアプリにメッセージを送信することがあります。ここで問題は、メモリ警告メソッドをオーバーライドしないときです。デフォルトのアクションは、表示されていないメモリからsubviewを削除することです。これにより、アプリケーションの実行時にゾンビ変数が発生する可能性があります。

は、この行は、これは私が見てきたものであるスタックトレースからクラッシュを引き起こしているapple doc

+0

私が思うに問題はないが、それは実際のアプリでオーバーライドされている。あなたはテストしましたか? – Oliver

関連する問題