UIViewControllers 如何创建 - alloc/init 与 performSegueWithIdentifier

How UIViewControllers created - by alloc/init vs. performSegueWithIdentifier

我的iOS8项目使用了Storyboard,其中我有一个UINavigationController,根UIViewController;我们称之为 A。我还有另一个 UIViewController,通过 Segue 连接到这个根控制器;我们称之为 B。相当标准的配置。

现在,AUITableViewController 的子类,在 table 中我有一个 URL 的列表.应用程序用户点击 table 单元格,URL 被提取并传递给 BB 是包含 WKWebView.

的子类 UIViewController

现在,因为 BUINavigationController 的堆栈上,用户可以在 B,返回到 table 和 URLs (A)。然后用户可以点击另一个单元格,以加载另一个 URL.

因为我需要将一些数据 (URL) 传递给 B,我用 performSegueWithIdentifier 调用它,并且在相应的 prepareForSegue 中,我将 URL 分配给 B 中的 属性。

一切正常。我的问题反映了我在 iOS 和 Objective-C.

方面的 still-nOOb 状态

第一个问题,当通过 performSegueWithIdentifier / prepareForSegue 组合创建 B 时,当用户点击后退按钮时, OS 是否释放了这个控制器?换句话说,不再有这个子类的实例 UIViewController 漂浮在周围?

如果是,那么如果用户点击 table 单元格以查看另一个 URL,那么创建它的新实例大概是安全的。也就是说,重复调用performSegueWithIdentifier,将新选择的URL赋值到B的属性,等等就是安全吗?

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

并且,无论哪种情况,在首次创建 B 时捕获对它的引用并继续重复使用它是否有意义?换句话说,在调用 performSegueWithIdentifier 之前,检查对 B 的引用是否已经存在,如果存在,则对该引用执行 pushViewControllerB?

所以基本问题归结为:在 UIViewController 需要多次可见的情况下 - 通过用户操作 - 是否每次需要时都新创建一个实例?如果是,那么这是否也意味着每个实例在不再需要时也在内部被释放?因此我不需要担心内部结构?

或者,如果我每次都继续使用 performSegueWithIdentifier,我是否只是在创建一堆控制器的新实例,因此既浪费又低效,而我只能捕获对第一个新实例的引用实例并继续重复使用它?

我尝试在调试器中逐步完成这个过程并跟踪引用,但我不确定我是否看到了我应该看到的东西,所以我正在询问更多知识渊博的开发人员。

感谢您阅读这个冗长的问题,并感谢您抽出时间来回答这个问题。

首先,当你推送视图和弹出视图时,如果你没有在其他任何地方保留该视图控制器,那么它将被完全释放,你调用 performSegueWithIdentifier 多少次来创建这个视图并不重要如果您没有保留或管理它参考不够好。 但是,在这种情况下,我会使用

创建您的 'B' 视图控制器
 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 实例,所以可以说它是有点膨胀..