EXC_BAD_ACCESS на iPhone (со снимком экрана отладчика)

Я разрабатываю приложение для 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, включив его в библиотеку, и попытаться отклонить ModalView.


person VansFannel    schedule 07.06.2010    source источник
comment
Эй, тебе удалось найти решение, как закрыть представление? В настоящее время у меня проблемы с просмотром AR. Был бы признателен за помощь, если у вас есть   -  person Spike Lee    schedule 02.09.2011
comment
Нет простите. Я не нашел решения этой проблемы.   -  person VansFannel    schedule 02.09.2011
comment
=/ так что я не думаю, что вы знаете какие-либо примеры, которые могут показать мне, как отклонить ar? я хочу, чтобы он вернулся в главное меню =/   -  person Spike Lee    schedule 02.09.2011
comment
Мне очень жаль, но я не работал с AR год назад. Возможно, вы могли бы попробовать другой AR SDK, например Qualcomm Augmented Reality SDK (QCAR). Есть ли бета-версия, которая работает с iOS 4.   -  person VansFannel    schedule 02.09.2011
comment
Вы можете найти его здесь: developer.qualcomm.com/develop/mobile-technologies/   -  person VansFannel    schedule 02.09.2011


Ответы (3)


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

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

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

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

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

person slf    schedule 07.06.2010
comment
как насчет rootViewController? - person slf; 07.06.2010
comment
это, вероятно, hte cameraController ... как его инициализировать? - person Daniel; 07.06.2010
comment
Ни один. Как видно на снимке экрана отладчика, вызывается последний метод (первый в стеке): [UIWindowController transitionViewDidComplete:fromView:toView]. Возможно, есть что-то, получающее доступ к изображению камеры после того, как она была закрыта. - person VansFannel; 07.06.2010
comment
@Daniel: я добавил инициализацию cameraController. - person VansFannel; 07.06.2010
comment
Вы выполняете какую-либо логику, чтобы спрятаться или спрятались, много раз люди забывают, что те стреляют - person slf; 07.06.2010
comment
Я не верю. Я добавил несколько трассировок NSLog, и после вызова hideAR кто-то снова вызывает displayAR. Когда я что-нибудь найду, я скажу тебе. - person VansFannel; 07.06.2010
comment
Синтезируется ли контроллер камеры с атрибутом сохранения? - person Daniel; 07.06.2010
comment
@Daniel: свойство контроллера камеры определяется следующим образом: @property (nonatomic, retain) UIImagePickerController *cameraController; - person VansFannel; 07.06.2010
comment
Наверное, я нашел ошибку. После hideAR вызывается viewDidAppear на roorViewController. Я обновил свой вопрос. - person VansFannel; 07.06.2010
comment
viewDidAppear вызывается всякий раз, когда представление снова появляется, что и происходит... ошибка, вероятно, вызвана из-за этого... просто чтобы посмотреть, не пытается ли он установить какой-то контроль, поэтому код внутри метода viewDidAppear выполняется только один раз и посмотреть, если который перестанет падать - person Daniel; 07.06.2010
comment
@Daniel: да, viewDidAppear - моя проблема. - person VansFannel; 07.06.2010
comment
Я нашел строку, которая выдает исключение, но я не знаю, почему. Я обновил свой вопрос с более подробной информацией. - person VansFannel; 08.06.2010
comment
@slf: я обновил свой вопрос, добавив информацию о том, как воспроизвести ошибку. Я изменил пример, добавив UIButton, рисующий программно, чтобы закрыть вид с камеры. Возможно, вы сможете воспроизвести ошибку. - person VansFannel; 09.06.2010
comment
@VansFannel вы получаете разные результаты с этим? github.com/zac/iphonearkit Это исходный фреймворк. - person slf; 09.06.2010
comment
@slf: Нет, я изменил все решение. И теперь это работает. Вместо того, чтобы использовать presentModalViewController для отображения камеры, теперь я использую ViewController, который наследуется от UIImagePickerController. - person VansFannel; 14.06.2010

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

Удачи

Жюль

person Jules    schedule 07.06.2010
comment
Спасибо. Я использую NSZombieEnabled как переменную окружения (установлено YES), но это не работает. - person VansFannel; 07.06.2010
comment
Что вы имеете в виду, когда говорите, что это не работает?? Выполняете ли вы следующий xcode›run›run с размещением объектов инструмента производительности?? Затем остановите выполнение (большой красной кнопкой) и нажмите кнопку информации по распределению объектов и установите флажок, чтобы включить обнаружение зомби и записать счетчики ссылок. Затем нажмите «Запись» и выполните последовательность, которая приводит к сбою вашего приложения. Когда происходит плохой доступ, он должен выделить строку кода, в которой находится ошибка. Удачи еще раз - person Jules; 07.06.2010
comment
Я нашел строку, которая выдает исключение, но я не знаю, почему. Я обновил свой вопрос с более подробной информацией. - person VansFannel; 08.06.2010

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

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

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

[[self accelerometerManager] release];

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

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

[self.view release];

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

person TechZen    schedule 07.06.2010
comment
Нет, я не нашел ничего подобного. Я обновил свой вопрос и думаю, что проблема в том, что viewDidAppear на rootViewController вызывается после hideAR вызова. - person VansFannel; 07.06.2010
comment
Я нашел строку, которая выдает исключение, но я не знаю, почему. Я обновил свой вопрос с более подробной информацией. - person VansFannel; 08.06.2010