未引用的对象是否可以保留在内存中并调用目标操作?

问题描述 投票:2回答:2

我有一个这样的课:

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子视图堆栈中?我认为它没有完全被破坏,因为它被父视图子视图引用了吗?我是否可以在不创建用于保存对象的局部变量(仅由子视图引用)的情况下使目标操作有效?

ios swift uiview selector
2个回答
2
投票

您不需要为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.
    }

}

当我运行这段代码时会发生什么:

clicking the red view makes it disappear

所以似乎点击红色Example视图使它像你想要的那样消失。


1
投票

是的,这是有效的,因为superview始终是其子视图的所有者。如果不是这样,iPhone上的大多数屏幕都会非常空,因为它们没有所有者。因此,对出口使用弱引用也是足够的。

© www.soinside.com 2019 - 2024. All rights reserved.