1

我正在开发一个 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 调用之后被调用。我还看到在 hideAR 之后也调用了该viewDidAppear方法。rootViewController实际上,viewDidAppear正在调用displayAR.

为什么叫viewDidAppear?

第四次更新

我找到了失败的线路。这是第一行displayAR

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

有任何想法吗? rootViewController并且cameraController不是零。

第五次更新

如果你想重现我的错误:

我正在使用 nielswh 的 iPhone-AR-Toolkit(你可以在这里下载)。

您可以修改 ARKitDemo 示例,将其包含在库中并尝试关闭 ModalView。

4

3 回答 3

1

几乎 100% 的时间 EXC_BAD_ACCESS 来自错误释放的资源。如果没有看到你所有的代码,就无法确定,但我最好的猜测accelerometerManagernil

编辑:

viewDidAppear 在根视图控制器上被调用,因为它现在在您显示的另一个视图被隐藏后再次呈现。

编辑2:

从堆栈跟踪的外观来看,某处某处注册了动画回调。完全有可能不管那个东西是什么,在显示/隐藏不同的视图之后它现在是无效的,并且可能在你不知情的情况下被释放。尝试找出正在侦听 animationDidStop 回调的内容,抱歉,我无法提供更多帮助,但没有剩下的所有代码都可以通过这个霰弹枪调试。

于 2010-06-07T14:21:41.103 回答
1

如果您还没有解决这个问题,您可以尝试使用仪器工具并启用僵尸检测。这节省了我几次,因为它会突出显示给你错误的确切代码行(大部分时间呵呵)

祝你好运

朱尔斯

于 2010-06-07T15:24:45.870 回答
0

崩溃发生在 API 代码的深处。这确实是模态视图或 self.view 的问题(假设 self 是视图控制器。)

您是否对控制器的主视图(例如 myController.view)做任何事情?如果你不小心杀死了非模态视图,当你从模态视图返回到它时,你会得到一个 Exec_Bad_Access。

我认为这很可能是因为:

[[self accelerometerManager] release];

... 表示您可能不了解如何管理属性。除了类的 dealloc 方法之外,您永远不会在任何地方释放保留的属性。属性的合成访问器应该管理保留,如果您在其他任何地方发布,您可以轻松地使实例认为它具有它没有的属性对象。

检查 dealloc 之外的控制器代码是否有类似的内容:

[self.view release];

如果你找到它,那很可能是你的问题。当然,视图引用或需要的任何属性被不当释放也可能导致问题。

于 2010-06-07T15:19:49.670 回答