假设我将视图控制器 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] 删除。
我来说两句