nielswh / iPhone-AR-Toolkit

An Objective-C augmented reality kit for iPhone. Forked from the iphonearkit.
http://www.agilitesoftware.com/blog
Other
275 stars 57 forks source link

memory leaks / release camera access #10

Closed coremjs closed 12 years ago

coremjs commented 12 years ago

when I test the ARKitDemo project on my device (iPhone4, iOS 4.0.x) the AR camera view can be opened / closed only once, when opening it again it takes a long time to open, and when it finally does, only a black screen is shown.

the reason for this behavior is because the AVCaptureSession is not releasing the camera and continues to block it.

I tried hacking around (based on 8c8793bbf8a8c76f4b281ae5c7066e22b22bb24a) - its quite unclean, but this solved it:

diff --git a/ARKit/AugmentedRealityController.m b/ARKit/AugmentedRealityController.m
index 65448cb..eb5331a 100644
--- a/ARKit/AugmentedRealityController.m
+++ b/ARKit/AugmentedRealityController.m
@@ -145,10 +145,15 @@

 - (IBAction)closeButtonClicked:(id)sender {
     [[self rootViewController] dismissModalViewControllerAnimated:YES];
+   //int rc1 = [self retainCount];
+   //int rc2 = self.rootViewController.retainCount;
+   self.rootViewController = nil;
+   [self unloadCamera];
 }

 -(void) unloadCamera {
     [self stopListening];
+   [self unloadAV];
 }

 - (void)startListening {
@@ -491,13 +496,28 @@
        [debugView removeFromSuperview];
 }

+- (void)unloadAV {
+   [captureSession stopRunning];
+   AVCaptureInput* input = [captureSession.inputs objectAtIndex:0];
+   [captureSession removeInput:input];
+   //AVCaptureVideoDataOutput* output = (AVCaptureVideoDataOutput*)[captureSession.outputs objectAtIndex:0];
+   //[captureSession removeOutput:output];
+   [self.previewLayer removeFromSuperlayer];
+   self.captureSession = nil;
+   self.previewLayer = nil;    
+}
+
 - (void)dealloc {
    [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
     [ARView release];
+   locationManager.delegate = nil;
+   [UIAccelerometer sharedAccelerometer].delegate = nil;
    [locationManager release];
    [coordinateViews release];
    [coordinates release];
    [debugView release];
+   
+   [self unloadAV];
     [super dealloc];
 }

diff --git a/ARKitDemo/Classes/MainViewController.m b/ARKitDemo/Classes/MainViewController.m
index e5ee613..031ca22 100644
--- a/ARKitDemo/Classes/MainViewController.m
+++ b/ARKitDemo/Classes/MainViewController.m
@@ -43,9 +43,10 @@
     ARKitDemoAppDelegate *appDelegate = (ARKitDemoAppDelegate*)[[UIApplication sharedApplication] delegate];

     if([ARKit deviceSupportsAR]){
-        [self setCameraViewController:[[ARViewController alloc] initWithDelegate:self]];
+        [self setCameraViewController:[[[ARViewController alloc] initWithDelegate:self] autorelease]];
         [cameraViewController setModalTransitionStyle: UIModalTransitionStyleFlipHorizontal];
         [self presentModalViewController:cameraViewController animated:YES]; 
+       self.cameraViewController = nil;
     }
     else {
         [self setInfoViewController:[[UIViewController alloc] init]];

it very likely still has memory leaks as well as problems when one actually wants to reuse the view (because of the forced unloadCamera)

nielswh commented 12 years ago

Thanks! I've made the changes in the latest release!