Iphone ARC:何时将viewController设置为零

Iphone ARC:何时将viewController设置为零,iphone,objective-c,ios5,automatic-ref-counting,Iphone,Objective C,Ios5,Automatic Ref Counting,我仍然在为ARC的想法而挣扎。让我们假设我有两个非常复杂的ViewController A和B,其中每个都有很多图片,每个视图都保留了这些图片。为了便于讨论,让我们假设第一个ViewController(A)保留了占用75MB内存的图像。另一个(B)也占用75MB 在我的应用程序委托中,我设置了导航控制器,如下所示: ViewControllerA *vcA = [[ViewControllerA alloc] init]; UINavigationController *navControll

我仍然在为ARC的想法而挣扎。让我们假设我有两个非常复杂的ViewController A和B,其中每个都有很多图片,每个视图都保留了这些图片。为了便于讨论,让我们假设第一个ViewController(A)保留了占用75MB内存的图像。另一个(B)也占用75MB

在我的应用程序委托中,我设置了导航控制器,如下所示:

ViewControllerA *vcA = [[ViewControllerA alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vcA];
[navController.navigationBar setHidden:YES];
[[self window] setRootViewController:navController];
当我从A切换到B时,我会在ViewControllerA中这样做。m:

ViewControllerB *vcB = [[ViewControllerB alloc] init];
[[self navigationController] pushViewController:vcB animated:YES];
当我切换回时,我会在ViewControllerB.m中这样做:

[[self navigationController] popToRootViewControllerAnimated:YES];
现在我的大问题是,当我在ViewController B中时,我的内存中是否仍然有ViewController A?在这种情况下,编译器何时释放ViewController?当一个ViewController不使用时,我是否可以或应该释放它(即将其设置为零)


如果答案很清楚或者我完全没有抓住要点,我很抱歉。因此,任何答案和解释都将不胜感激。

是的,您还有ViewControllerA(您下次可以在仪器上看到)。这与弧无关,没有弧也一样。让我解释一下:

您创建了一个UINavigationController,并将UIViewController a作为根,a被保留(在ARC中,它是一个强属性或类似的东西),正如您所看到的,UINavigationController需要它,对吗? 现在你推UIViewController B,B和A在内存中存在,你的UINavigationController仍然需要UIViewController A,如果系统需要内存,它只是不显示,视图可以卸载,但它不会释放A。当你弹出UIViewController B时,它被释放,如果没有它的引用(同样,我假设ARC是这样工作的)它被解除分配

现在您的问题是,rootViewController何时解除分配?嗯,UINavigationController总是有根的!因此,当您有一个UINavigationController时,您有一个rootViewController


如果您需要进一步解释,请在评论中告诉我。

我无法帮助您使用ARC,因为我从未使用过它(我不知道是否真的需要)

但我可以告诉你一件事:

推送ViewController时,它们都在导航堆栈中。直到它们在堆栈中,它们都会保留在内存中

在不使用ARC的情况下,如果我自动释放我按下的eatch viewController,它将在我将其从堆栈中弹出时被释放

如果有人知道更多关于ARC的信息(以及当它发布分配对象时),我会很高兴得到更多信息


谢谢

您的视图控制器A将由
navController
保留,因此它不会被释放。即使您将
vcA
设置为nil,它也不会被释放,因为
navController
正在保留它。 问题是控制器保留了大量占用大量内存的资源(图像)。要解决这个问题,您可以在
viewDidLoad
上分配资源,并在
viewDidUnload

比如说

// in your view controller
- (void)viewDidLoad {
    [super viewDidLoad];
    self.image = // read image to memory
}

- (void)viewDidUnload {
    [super viewDidUnload];
    self.image = nil; // release the image to free memory
}

然后,在视图控制器B被推送到navController之后,UIKit会通知视图控制器A它不是显示控制器,如果需要,它会卸载视图,以便释放内存供其他类使用。

对不起,我认为您弄错了。ViewDidLoad和ViewDidUnload在创建视图时和销毁视图之前(在解除锁定之前)调用。也许您想讨论ViewWillExample和ViewWillEnglishe方法,它们在viewController的视图显示/隐藏时被称为eatch。最后,这是我自己的观点,我认为最好只加载一次图像,特别是如果控制器经常显示。如果每次视图出现/消失时都分配和释放图像,那么每次视图更改都将是一个扩展操作,可能会导致应用程序滞后。UIKit知道何时卸载视图以节省不必要的加载/卸载工作。我完全同意你的看法。我想说的是,在viewDidLoad/viewDidUnload中alloc/release图像与在,例如,initWithNibName/Dealloc方法。视图控制器可以多次借用/卸载其视图,但只能借用/卸载一次init/Dealloc,只有在需要比较加载init中的所有内容时,load view和其他资源之间才会有所不同