UIViewControllers如何创建 - 通过alloc / init与performSegueWithIdentifier

时间:2015-07-11 14:33:05

标签: objective-c uiviewcontroller ios8 uinavigationcontroller

我的iOS 8项目使用了一个故事板,其中我有一个UINavigationController,其根目录为UIViewController;我们称之为 A 。我还有另一个UIViewController,通过Segue连接到这个根控制器;我们称之为 B 。非常标准的配置。

现在, A 是一个子类UITableViewController,在表格中我有一个网址列表。应用用户点击表格单元格,提取网址并传递给 B B 是包含UIViewController的子类WKWebView

现在,因为 B 位于UINavigationController的堆叠上,用户可以在 B <中点按“返回”按钮/ strong>,返回包含网址的表格( A )。然后,用户可以点击另一个单元格,以加载另一个URL。

因为我需要将一些数据(网址)传递给 B ,所以我使用performSegueWithIdentifier和相应的{{1}调用它},我将网址分配给 prepareForSegue 中的媒体资源。

一切正常。我的问题反映了我对iOS和Objective-C的静态状态。

第一个问题,当通过B / B组合创建 performSegueWithIdentifier 时,当用户点按“返回”按钮时,此控制器是否已取消分配操作系统?换句话说,这个子类prepareForSegue的实例不再是浮动的吗?

如果是,那么如果用户点击表格单元格以查看另一个URL,则可能安全地创建它的新实例。换句话说,重复拨打UIViewController,在 performSegueWithIdentifier 的属性中分配新选择的网址等。是否安全?

或者,如果它没有自动解除分配,那么重复调用B等,只是继续创建越来越多的 performSegueWithIdentifier 实例?

而且,在任何一种情况下,首次创建 B 时,是否有意义捕获对它的引用,并继续重复使用它?换句话说,在调用B之前,请检查是否已存在对 performSegueWithIdentifier 的引用,如果存在,请执行B并引用 pushViewController

因此,基本问题归结为:在需要多次显示B的情况下 - 通过用户操作 - 是每次需要时新创建的实例?如果是,那么这是否也意味着每个实例在不再需要时也会在内部解除分配?因此,我不需要担心内部情况?

或者,如果我每次都继续使用UIViewController,那么我只是创建了一堆控制器的新实例,因此当我可以捕获对第一个新实例的引用时,它是浪费和低效的。继续使用它?

我已经尝试在调试器中逐步完成此过程并跟踪引用,但我不确定我是否看到了应该看到的内容,因此我就是这样询问更多知识渊博的开发人员。

感谢您阅读这个长期的问题,以及您回答它的时间。

1 个答案:

答案 0 :(得分:1)

首先,当您按下视图和弹出视图时,如果您没有在其他地方保留该视图控制器,那么它将完全释放,并且调用performSegueWithIdentifier创建此视图的时间并不重要如果您没有保留它或管理它参考得足够好。 但是,在这种情况下,我会创建你的&#39; B&#39;使用

查看控制器
 self.bController = [self.storyboard instantiateViewControllerWithIdentifier:@"BController"];

然后你使用self.bController调用pushViewController,函数会看起来像这样..

- (void)presentURL:(NSString*)url
{
    if ( self.bController == nil ) {
        self.bController = [self.storyboard instantiateViewControllerWithIdentifier:@"BController"];
    }

    [self.bController setURL:url];

    [viewController.navigationController pushViewController:self.bController animated:YES];
}

在设置URL时使用以下代码刷新WKWebView

-(void)setUrlString:(NSString *)urlString {
    // set url string
    _urlString = urlString;

    // clear
    [self.webView loadHTMLString:@"" baseURL:nil];

    // load url with string
    if( _urlString != nil ) {
        // get address for hosting view
        NSURL* url = [NSURL URLWithString:_urlString];
        NSURLRequest* urlRequest = [NSURLRequest requestWithURL:url];
        [self.webView loadRequest:urlRequest];
    }
}

它会比prepareForSegue更简单,但是,再次重复调用performSegueWithIdentifier,在B的属性中分配新选择的URL等。只要你不保留就完全安全其他任何地方..但性能明智它可能比保持B viewController的一个实例并多次显示它有点贵,因为它必须读取并启动视图控制器和WKWebView实例所以可以说它有点膨胀..