在导航控制器中取消分配具有 self 引用的视图控制器

用户7804097

假设我将视图控制器 A、B、C、D 和 E 都嵌入到导航控制器中。在视图控制器 B 中,我有一个自定义 UIImageView 对象。在 C 中,我有一个自定义 UITextfield 对象。由于各种原因,两个自定义类都引用了视图控制器,例如当用户点击图像视图时我必须执行诸如 segue 之类的操作。为了实现这一点,我在每个自定义类文件中都有这个:

var controller: UIViewController?

然后在每个视图控制器中,在 viewDidLoad 中我将该变量设置为 self 并且一切都按预期工作(segues on tap等..)

我有一个从 E 回到 A 的 unwind segue。但是,我注意到由于视图控制器 B 和 C 中的这些自定义对象,由于对视图控制器的此引用导致的保留周期,它们都没有被释放。我通过在 segue 时将控制器变量设置为 nil 解决了这个问题,但是这会产生一个问题,如果用户返回(弹出当前视图控制器),因为我在 segue 时将控制器变量设置为 nil,没有任何作用(它不会再次继续,因为控制器 var = nil)。我想我可以通过添加 viewWillAppear 代码来解决这个问题,如下所示:

 override func viewWillAppear(_ animated: Bool) {
    usernameTextField.controller = self
    passwordTextField.controller = self
}

因为我读到每次视图控制器进入视图时都会调用 viewWillAppear 。这并没有解决问题。

关于如何解决这个问题的任何想法?如何在放松期间将控制器设置为 nil 可能......?

真理的拥护者

正如其他答案所说,您需要使其成为这样的弱参考:

weak var controller: UIViewControler?

但是,我会更进一步说,您不应该在任何基于 UIView 的对象(UIImageView、UITextField 等)中保留对 UIViewController 的引用。UIViews 不需要知道关于它们的 UIViewControllers 的任何信息。

相反,您应该使用委托模式。这是一个基本示例:

1)为自定义 UIImageField 创建一个协议,如下所示:

protocol MyImageFieldProtocol: class {
    func imageTapped()
}

2)然后添加一个这样的委托:

weak var delegate: MyImageFieldProtocol?

3) 然后你的 UIViewController 符合这样的协议:

class MyViewController: UIViewController, MyImageFieldProtocol {
}

4) 视图控制器内部的某处(viewDidLoad 通常是您将视图控制器分配给图像视图委托的好地方,如下所示:

func viewDidLoad {
    super.viewDidLoad()
    myImageView.delegate = self
}

5)然后添加函数来响应协议动作到视图控制器,如下所示:

func imageTapped {
    self.performSegue(withIdentifier: "MySegue", sender: nil)
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

iOS-具有对父视图控制器的“强大”引用的子视图控制器

是否从导航堆栈弹出视图控制器取消分配?

self.window在视图控制器中不起作用

self.view.frame.width在自定义键盘视图控制器中返回0

具有相同根视图的导航控制器

在推送导航控制器的视图控制器中实现 MapKit 的有效方法?

如何从情节提要中绘制的现有视图控制器构建导航控制器?

导航控制器推式视图控制器

从导航控制器移回视图控制器?

取消视图控制器的取消锁定

获取对容器视图的视图控制器的引用

self.navigationController?.popToRootViewController(animated: true) 不会关闭任何呈现的视图控制器

AVSpeechSynthesizer不允许视图控制器取消分配

取消推送的视图控制器

如何在导航视图控制器中关闭整个视图控制器堆栈?

从控制器外部呈现视图控制器,无需传递自引用

self.tabBarController?.selectedIndex并在另一个视图控制器中执行功能

将导航栏添加到没有导航控制器的视图控制器中

在视图内创建导航控制器

过渡到导航视图控制器

隐藏视图控制器的导航栏

模态视图中的导航控制器

在视图控制器之间快速导航

在视图控制器之间导航的按钮

在具有父视图控制器中公开的objc功能的视图控制器中使用选择器

如何获得对主视图控制器的引用?

如何引用子类的父视图控制器?

iOS根据视图控制器标题引用特定词典

以模态方式呈现嵌入在导航控制器中的视图控制器,与标签栏控制器分开