EXC_BAD_ACCESS на iPhone (со скриншотом отладчика) - PullRequest
1 голос
/ 07 июня 2010

Я разрабатываю приложение для iPhone, которое показывает вид камеры с помощью этого кода:

-(void) displayAR {
    [rootViewController presentModalViewController:[self cameraController] animated:NO];
    [displayView setFrame:[[[self cameraController] view] bounds]];
}

И скрыть вид камеры с помощью этого кода:

- (void) hideAR {
    [[self locationManager] stopUpdatingHeading];
    [[self locationManager] stopUpdatingLocation];

    [[self accelerometerManager] release];

    [rootViewController dismissModalViewControllerAnimated:YES];
}

Когда я вызываю hideAR, я получаю EXC_BAD_ACCESS со следующим снимком экрана отладчика:

альтернативный текст http://img408.imageshack.us/img408/4550/capturadepantalla201006u.png

Любой совет?

ОБНОВЛЕНИЕ:

Я изменил код hideAR с этим и получаю ту же ошибку:

- (void) hideAR {

    [rootViewController dismissModalViewControllerAnimated:YES];
}

Я проверил rootViewController, и это не ноль.

Как видно на скриншоте отладчика, последний вызванный метод (первый в стеке): [UIWindowController transitionViewDidComplete:fromView:toView].

Может быть, после того, как камера была закрыта, есть что-то доступное к виду камеры.

ВТОРОЕ ОБНОВЛЕНИЕ

Класс, содержащий эти методы:

@implementation AugmentedRealityController

@synthesize locationManager;
@synthesize accelerometerManager;
@synthesize displayView;
@synthesize centerCoordinate;
@synthesize scaleViewsBasedOnDistance;
@synthesize rotateViewsBasedOnPerspective;
@synthesize maximumScaleDistance;
@synthesize minimumScaleFactor;
@synthesize maximumRotationAngle;
@synthesize centerLocation;
@synthesize coordinates = coordinates;
@synthesize debugMode;
@synthesize currentOrientation;
@synthesize degreeRange;
@synthesize rootViewController;

@synthesize cameraController;

- (id)initWithViewController:(UIViewController *)vc {

    coordinates     = [[NSMutableArray alloc] init];
    coordinateViews = [[NSMutableArray alloc] init];
    latestHeading   = -1.0f;
    debugView       = nil;

    [self setRootViewController: vc];

    [self setDebugMode:NO];
    [self setMaximumScaleDistance: 0.0];
    [self setMinimumScaleFactor: 1.0];
    [self setScaleViewsBasedOnDistance: NO];
    [self setRotateViewsBasedOnPerspective: NO];
    [self setMaximumRotationAngle: M_PI / 6.0];

    CGRect screenRect = [[UIScreen mainScreen] bounds];

    [self setDisplayView: [[UIView alloc] initWithFrame: screenRect]];

    [self setCurrentOrientation:UIDeviceOrientationPortrait];
    [self setDegreeRange:[[self displayView] bounds].size.width / 12];

    [vc setView:displayView];

    [self setCameraController: [[[UIImagePickerController alloc] init] autorelease]];
    [[self cameraController] setSourceType: UIImagePickerControllerSourceTypeCamera];
    [[self cameraController] setCameraViewTransform: CGAffineTransformScale([[self cameraController] cameraViewTransform], 1.13f,  1.13f)];
    [[self cameraController] setShowsCameraControls:NO];
    [[self cameraController] setNavigationBarHidden:YES];
    [[self cameraController] setCameraOverlayView:displayView];

    CLLocation *newCenter = [[CLLocation alloc] initWithLatitude:37.41711 longitude:-122.02528];

    [self setCenterLocation: newCenter];
    [newCenter release];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(deviceOrientationDidChange:)
                                                 name: UIDeviceOrientationDidChangeNotification
                                               object:nil];
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];   

    // Inicializa el gestor del GPS y el del acelerómetro.
    [self startListening];

    return self;
}

ТРЕТЬЕ ОБНОВЛЕНИЕ

Я поставил некоторую трассировку NSLog и вижу, что displayAR вызывается после вызова hideAR. Я также вижу, что метод viewDidAppear на rootViewController также вызывается после hideAR. На самом деле, viewDidAppear звонит displayAR.

Почему он называется viewDidAppear?

ЧЕТВЕРТОЕ ОБНОВЛЕНИЕ

Я нашел линию, которая терпит неудачу. Это первая строка на displayAR:

[rootViewController presentModalViewController:[self cameraController] animated:NO];

Есть идеи? rootViewController и cameraController не равны нулю.

ОБНОВЛЕНИЕ ФИТ

Если вы хотите воспроизвести мою ошибку:

Я использую iPhone-AR-Toolkit от nielswh (его можно загрузить здесь ).

Вы можете изменить пример ARKitDemo, включить его в библиотеку и попробовать dismissModalView.

Ответы [ 3 ]

1 голос
/ 07 июня 2010

если вы еще не решили эту проблему, вы можете попробовать использовать инструмент инструменты и включить обнаружение зомби. Это спасло меня пару раз, так как выделит точную строку кода, которая выдает ошибку (большую часть времени хе-хе)

Удачи

Jules

1 голос
/ 07 июня 2010

Почти 100% времени EXC_BAD_ACCESS исходит из ошибочно выпущенного ресурса.Не видя весь ваш код, невозможно точно узнать, но я думаю, что accelerometerManager равно nil

РЕДАКТИРОВАТЬ:

viewDidAppear вызывается на контроллере корневого представления, потому чтотеперь он отображается снова после того, как другой вид, который вы отображали, был скрыт.

РЕДАКТИРОВАТЬ 2:

Судя по вашей трассировке стека, что-то где-то когда-то было зарегистрировано для анимационного обратного вызова.Вполне возможно, что независимо от того, что это за штука, она теперь недействительна после того, как показывает / скрывает разные взгляды, и могла быть выпущена без вашего ведома.Попытайтесь выяснить, что именно прослушивает обратный вызов animationDidStop, извините, я не могу помочь больше, но не имея всего кода, который у нас остался с этой отладкой ружья.

0 голосов
/ 07 июня 2010

Сбой происходит глубоко в коде API. Это действительно должно быть проблемой либо с модальным представлением, либо с self.view (при условии, что self является контроллером представления.)

Делаете ли вы что-нибудь для основного представления контроллера, например, myController.view? Если вы случайно убили немодальное представление, когда вы вернетесь к нему из модального представления, вы получите Exec_Bad_Access.

Я думаю, что это вероятно, потому что это:

[[self accelerometerManager] release];

... означает, что вы не понимаете, как управлять свойствами. Вы никогда не освобождаете сохраненное свойство нигде, кроме метода dealloc класса. Предполагается, что синтезированные средства доступа к свойствам управляют хранением, и если вы выпускаете что-либо еще, вы можете легко заставить экземпляр думать, что у него есть объект свойства, которого у него нет.

Проверьте код вашего контроллера за пределами dealloc на предмет чего-либо похожего на:

[self.view release];

Если вы найдете это, скорее всего, это ваша проблема. Конечно, любое свойство, к которому относится это представление, или потребности, которые были неправильно освобождены, также могут быть причиной проблемы.

...