返回主视图时如何从内存中删除子视图?

时间:2011-09-03 17:52:08

标签: ios xcode uiviewcontroller

假设我有一个主视图,当我点击一个按钮时,它会加载一个子视图并让该子视图启动手电筒(LED),然后当我返回主视图时,它将释放子视图并关闭手电筒(LED)

- (void)loadView
{
    [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]];

    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

    // If torch supported, add button to toggle flashlight on/off
    if ([device hasTorch] == YES)
    {  
        // Create an AV session
        AVCaptureSession *session = [[AVCaptureSession alloc] init];

        // Create device input and add to current session
        AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error: nil];
        [session addInput:input];

        // Create video output and add to current session
        AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
        [session addOutput:output];

        // Start session configuration
        [session beginConfiguration];
        [device lockForConfiguration:nil];

        // Set torch to on
        [device setTorchMode:AVCaptureTorchModeOn];

        [device unlockForConfiguration];
        [session commitConfiguration];

        // Start the session
        [session startRunning];

        // Keep the session around
        [self setAVSession:session];

        [output release];

    }
}

现在,当我关闭子视图时,它应该从内存中释放并停止手电筒。

- (void)viewDidUnload
{
    [self.view removeFromSuperview];
    [self autorelease];
    [AVSession stopRunning];
    [AVSession release], AVSession = nil;
    [super viewDidUnload];
}

但是这个viewDidUnload的东西不起作用,请告诉我我做错了什么。

2 个答案:

答案 0 :(得分:3)

问题在于你误解了-viewDidLoad的目的。

-viewDidUnload仅在系统尝试释放内存时在内存不足的情况下调用。在这种情况下,非活动视图控制器将释放其视图并调用-viewDidUnload,以便您可以释放任何与视图相关的资源。

当视图控制器变为非活动状态或视图控制器被释放时,不要指望被调用-viewDidUnload

您的视图控制器可能知道AVSession何时应该结束,并且只要它能够解决,就可以结束会话。

顺便说一下,-viewDidUnload从未跑过是件好事;对[self autorelease]的调用可能会导致崩溃。你为什么这样做?您显示的代码是视图控制器的一部分。我不知道那个班级的名字是什么,所以我想象它是FlashlightViewController。据推测,其他一些视图控制器正在实例化FlashlightViewController并以某种方式使其处于活动状态,如下所示:

FlashlightViewController *fvc = [[FlashlightViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:fvc];
[fvc release];

此处,导航控制器在按下时将保留fvc,并且创建fvc的控制器会释放它,因为它不再需要对新控制器的引用。当手电筒控制器完成其工作并从导航堆栈中弹出时,导航控制器将释放它。由于没有其他对象保留手电筒控制器,因此将自动取消分配。当发生这种情况时,它将释放其视图,并且由于没有其他对象保留视图,因此视图也将被释放。

您的情况的详细信息可能有所不同,但想法始终相同:视图控制器和视图将在视图控制器释放后从内存中删除。

答案 1 :(得分:2)

您可能正在保留视图控制器,并且决定将视图保留在内存中,以防您的应用决定再次显示它(这是Caleb在评论中提到的缓存)。仅仅因为视图不可见并不意味着它会被卸载。

如果你有内存泄漏(这里我的意思是VC),显然修复它是有意义的。

但是,我认为启用和禁用手电筒的最佳选择是在viewDidAppear和viewDidDisappear(或它们的..will ..变体)中执行此操作。