(完全なソースコードが含まれています)狂気私を駆動する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
私たちのために小さなアプリケーションを作成して、mediafire.comや他のいくつかのウェブサイトにアップロードして、ここにURLを投稿してもらうことができますか?プロジェクトを作成してコードをコピーしてデバッグするのはあまりにも怠惰です。 – ARC
@Nikita:ok、done、my editを参照してください – Oliver
[self.myMapView removeAnnotation:self.myMapView.userLocation]; //この行はstacktraceからクラッシュする原因となっています。これは私が見たものです。 – ARC