iphone - 在内存警告消失后如何从 XIB 重新加载 UIViewController 的 View ?

标签 iphone ios memory-management uiviewcontroller xib

我有一个用 XIB 初始化的 iPhone View Controller 。

如果在出现内存警告时 View Controller 的 View 不可见,它将其 View 设置为 nil(释放它)。但是当一个重叠的 View 被关闭并且被清除的 View 再次变得可见时,Cocoa 不会从 XIB 重新加载它;它只是创建一个空白的。这会留下一个空白的白屏和一个损坏的应用程序。

UIViewController 的 loadView 方法的 Apple 文档说,“如果 View Controller 有一个关联的 nib 文件,这个方法从 nib 文件加载 View 。如果 View Controller 有一个关联的 nib 文件, nibName 属性返回一个非零值。”所以我覆盖了 loadView 只是为了在初始化 Controller 后检查 nibNamenibName 是正确的。因此对 loadView 的后续调用应该从 XIB 重新加载。我验证了内存警告后再次调用了 loadView

更新:通过更多的测试和记录,我确定在第二次 viewDidLoad 调用之后, View 的 IBOutlets 不为零。由于我在 viewDidUnload 中将它们设置为 nil,因此我得出结论,该 View 确实是从 XIB 重新加载的。那么为什么它显示为全白屏幕?

感谢您的任何见解。

这是viewDidLoad:

- (void)viewDidLoad
{
    [super viewDidLoad];

    _photoViewController = [[EGOSimplePhotoViewController alloc] initWithPhotoSource:_photoSource
                                                                      scrollView:bigImageScrollView
                                                                     enclosingView:photoSquare];
    _photoViewController.delegate = self;

    if(_progressHUD == nil)
    {
        if(self.navigationController.view != nil)
        {
            _progressHUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
        }
        else
        {
            _progressHUD = [[MBProgressHUD alloc] initWithView:self.view];
        }
    }

    // Add HUD to screen.
    if(self.navigationController.view != nil)
    {
        [self.navigationController.view addSubview:_progressHUD];
    }
    else
    {
        [self.view addSubview:_progressHUD];
    }

    [_progressHUD release];

    _progressHUD.labelText = @"Loading...";
    [_progressHUD show:YES];
}

viewDidUnload:

- (void)viewDidUnload
{
    [_photoViewController release];
    [super viewDidUnload];
}

最佳答案

内存警告后的 viewControllers View 加载机制应该对开发人员是透明的。您不必做任何事情来重新创建 View 。

对于使用nib加载的VC,系统会重新创建 View 并调用viewDidLoad。 对于以编程方式加载的 VC,将再次调用 loadView。

整个循环重复直到 viewDidAppear: 并且您再次看到 View 。

用例:

UITabBarController(假设有 2 个标签)

选项卡 0 上的用户 >> 转到选项卡 1 >> 触发内存警告 >> UITabbarController 上的所有事件 VC 收到内存警告 >> UITabBarController 将卸载 Tab0 的 View >> Tab0 接收 viewDidUnload:

当用户切换回 Tab 0 时,它的 View 将按照我所说的从 loadView 或 viewDidLoad 开始从头开始创建。

如果您没有收到这些事件,那么您的 viewController 层次结构就乱套了。也许你只是将​​一些 VC View 作为 subview 添加到某些东西,或者你的 VC 没有直接连接到窗口,或者通过一些容器 Controller (UINavigation,UITabBarController 等)或者你可能尝试卷起你自己的 containerController 并搞砸了。

尝试理解从 loadView 到 viewDidUnload 和 dealloc 的 UIViewController 生命周期。这很棒。这将有助于编写良好的代码和设计您的应用程序。

关于iphone - 在内存警告消失后如何从 XIB 重新加载 UIViewController 的 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9493734/

相关文章:

iphone - setStatusBarHidden :Yes?后如何设置顶部位置= 0

iphone - 在 iPhone 5 和 iPhone 4 的 xib 中处理不同尺寸的图像?

ios - 使用通用协议(protocol)实例化 ViewModel 数据

c++ - 链表的链表的析构函数

iphone - 核心数据获取: Sort by relationship count

iphone - UIImageView 动画慢

c - 使用 realloc 缩小分配的内存

QT QProcess内存管理

iphone - 以编程方式设置用户位置的坐标 Xcode/Objective-C

ios - 在 UITextView 中格式化文本