Я разрабатываю приложение для 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
не ноль.
ОБНОВЛЕНИЕ FITH
Если Вы хотите воспроизвести мою ошибку:
Я использую ИНСТРУМЕНТАРИЙ AR IPHONE nielswh (можно загрузить его здесь).
Можно изменить пример ARKitDemo, включают его с библиотекой и пробуют к dismissModalView.
Почти в 100% случаев EXC_BAD_ACCESS исходит из ошибочно освобожденного ресурса. Не видя весь ваш код, невозможно узнать наверняка, но я могу предположить, что AccelerometerManager
равен nil
РЕДАКТИРОВАТЬ:
viewDidAppear вызывается на контроллере корневого представления, потому что он теперь отображается снова после того, как другое отображаемое вами представление было скрыто.
РЕДАКТИРОВАТЬ 2:
Судя по трассировке стека, что-то где-то когда-то регистрировалось для обратного вызова анимации. Вполне возможно, что что бы это ни было, теперь оно недействительно после отображения / скрытия различных представлений и могло быть выпущено без вашего ведома. Попытайтесь унюхать, что именно прослушивает обратный вызов animationDidStop, извините, я ничем не могу помочь, но без всего кода, который у нас остался с этой отладкой дробовика.
Сбой происходит глубоко в коде API. Это действительно должна быть проблема либо с модальным представлением, либо с self.view (при условии, что self является контроллером представления.)
Делаете ли вы что-нибудь с основным представлением контроллера, например, myController.view? Если вы случайно отключите немодальное представление, когда вы вернетесь к нему из модального представления, вы получите Exec_Bad_Access.
Я думаю, это вероятно, потому что это:
[[self accelerometerManager] release];
... означает, что вы не понимаете, как управлять свойствами. Вы никогда, никогда не освобождаете сохраненное свойство где-либо, кроме метода dealloc класса. Предполагается, что синтезированные аксессоры для свойств управляют хранением, и если вы отпустите где-нибудь еще, вы можете легко заставить экземпляр думать, что у него есть объект свойства, которого у него нет.
Проверьте код вашего контроллера за пределами dealloc, нет ли чего-нибудь похожего на:
[self.view release];
Если вы его нашли, скорее всего, это ваша проблема. Конечно, любое свойство, на которое ссылается представление, или необходимость, которое было неправильно освобождено, также может вызвать проблему.
если вы еще не решили эту проблему, попробуйте использовать инструмент instruments и включить обнаружение зомби. Это спасло меня пару раз, так как выделит точную строку кода, которая выдает ошибку (в большинстве случаев)
Удачи
Jules