我有一个这样的课:
class Example: UIView {
init(frame: CGRect) {
super.init(frame: frame);
let tap = UITapGestureRecognizer(target: self, action: #selector(dismiss(_:)));
self.addGestureRecognizer(tap)
self.isUserInteractionEnabled = true;
self.backgroundColor = UIColor.red;
}
func show(parentView: UIView) {
parentView.addSubview(self);
}
@objc func dismiss(_ sender: UITapGestureRecognizer? = nil) {
self.removeFromSuperview();
}
}
然后我想这样称呼它:
override func viewWillAppear() {
super.viewWillAppear();
Example.init(frame: self.view.bounds).show(parentView: self.view);
}
视图以预期的红色背景显示。但当我点击视图时,什么也没发生。甚至没有调用dismiss函数。
但如果这样做:
var example : UIView!;
override func viewWillAppear() {
super.viewWillAppear();
example = Example.init(frame: self.view.bounds);
example.show(parentView: self.view);
}
水龙头工作正常。我怀疑这是因为沿途的物体被破坏了?但它仍然存在于UIView
子视图堆栈中?我认为它没有完全被破坏,因为它被父视图子视图引用了吗?我是否可以在不创建用于保存对象的局部变量(仅由子视图引用)的情况下使目标操作有效?
您不需要为Example
的实例创建一个ivar。通过调用show(parent:)
,您最终将其添加到视图层次结构中,该层次结构保留了它。所以它留在记忆中。
如果我在一个全新的Xcode单视图应用程序项目中运行您的示例代码,它在没有ivar的情况下工作正常。我的代码是:
import UIKit
class Example: UIView {
override init(frame: CGRect) {
super.init(frame: frame);
let tap = UITapGestureRecognizer(target: self, action: #selector(dismiss(_:)));
self.addGestureRecognizer(tap)
self.isUserInteractionEnabled = true;
self.backgroundColor = UIColor.red;
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func show(parentView: UIView) {
parentView.addSubview(self);
}
@objc func dismiss(_ sender: UITapGestureRecognizer? = nil) {
self.removeFromSuperview();
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
Example.init(frame: self.view.bounds).show(parentView: self.view);
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
当我运行这段代码时会发生什么:
所以似乎点击红色Example
视图使它像你想要的那样消失。
是的,这是有效的,因为superview始终是其子视图的所有者。如果不是这样,iPhone上的大多数屏幕都会非常空,因为它们没有所有者。因此,对出口使用弱引用也是足够的。