假设我有一个主视图,当我点击一个按钮时,它会加载一个子视图并让该子视图启动手电筒(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的东西不起作用,请告诉我我做错了什么。
答案 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 ..变体)中执行此操作。