【问题标题】:Can I retain a View while releasing its ViewController?我可以在释放 ViewController 的同时保留 View 吗?
【发布时间】:2009-07-10 00:26:49
【问题描述】:

我正在尝试将新视图加载到现有视图控制器中,但我想从 xib 文件加载该视图。我的计划是创建第二个 viewController(下面代码中的 viewController1),然后保留它的视图并释放我刚刚创建的那个 viewController。我希望 viewController 会被释放并且视图会一直存在,但这似乎没有发生。

问题 1:如果视图控制器被解除分配,无论视图的保留计数是多少,它的关联视图是否也会被解除分配?在下面的示例代码中,您可以看到视图在突然消失之前的保留计数为 13。

问题2:为什么保留视图会使它的retainCount增加3?

PageViewController *viewController1 = [[PageViewController alloc] initWithNibName:@"Page1" bundle:nil];
[viewController1.view setUserInteractionEnabled:YES];

NSLog (@"vc retain count: %d", [viewController1 retainCount]); //count=1
NSLog (@"vc view retain count: %d", [viewController1.view retainCount]); //count=4

self.currentPageView=viewController1.view;

NSLog (@"vc retain count: %d", [viewController1 retainCount]); //count=1
NSLog (@"vc view retain count: %d", [viewController1.view retainCount]); //count=7


[viewController1.view retain];

NSLog (@"vc retain count: %d", [viewController1 retainCount]); //count=1
NSLog (@"vc view retain count: %d", [viewController1.view retainCount]); //count=10

[self.view addSubview:viewController1.view];

NSLog (@"vc retain count: %d", [viewController1 retainCount]); //count=1
NSLog (@"vc view retain count: %d", [viewController1.view retainCount]); //count=13

[viewController1 release];

NSLog (@"vc view retain count: %d", [viewController1.view retainCount]); 
//objc[3237]: FREED(id): message view sent to freed object=0x538ce0

【问题讨论】:

    标签: iphone cocoa-touch uiview uiviewcontroller


    【解决方案1】:

    您收到的关于“发送到已释放对象的消息”的错误并不是告诉您 view 已被释放,而是 viewController1 已被释放,因此您当您向其发送“查看”消息时再次收到错误消息。 (请记住,在 Objective C 中,每个属性访问都会发送一条消息……)

    不过,我不确定为什么视图的保留计数每次都会增加 3。

    【讨论】:

    • 谢谢,我仍然没有弄清楚为什么每次保留计数都会增加 3,但我认为这已经够混乱了,我将尝试重构一些东西以避免问题完全。我希望我有足够的声誉来投票支持 Hikaru 在下面的答案,而且这也很有帮助。
    【解决方案2】:

    这可能会有所帮助:

    [[NSBundle mainBundle] loadNibNamed:@"Page1" owner:self options:nil];
    

    其中 self 是现有的 viewController。

    【讨论】:

      【解决方案3】:

      这条线毫无意义

      self.currentPageView=viewController1.view;

      viewController1 中的视图尚未构建,因为该控制器中的方法 loadView 未被调用

      尽管您可以将新的子视图添加到 viewController.view 中,因为“魔法”允许您将对象添加到尚未构建的视图中。

      这并没有改变事实 - viewController.view 当时不存在。

      注意:所有的controller.view都内置在viewDidLoad/loadView方法中,viewDidLoad/loadView在显示之前不会调用(例如pushController)

      通常我不依赖保留计数器,因为它不可靠。

      【讨论】:

        猜你喜欢
        • 2013-02-17
        • 1970-01-01
        • 1970-01-01
        • 2011-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多