UIView superview属性弱还是强?

时间:2016-12-14 11:39:12

标签: ios xcode uiview uikit superview

UIView标头声明superview属性很强

open var superview: UIView? { get }

但它的行为就像一个弱属性,即如果我创建view1和view2然后调用view1.addSubview(view2),然后只保存一个强引用到view2(而不是view1),view1将被删除,即使view2通过superview属性引用它。

所以,我想知道它是如何在现实中实施的。

编辑:例如,此代码打印“deinit”(ViewController实例显示在屏幕上),这意味着view1已被删除,即使view2应该通过superview属性强烈保留它。

class View: UIView {
    deinit {
        print("deinit")
    }
}

class ViewController: UIViewController {

    var view2 = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()

        let view1 = View()
        view1.addSubview(view2)
    }
}

3 个答案:

答案 0 :(得分:7)

Oleg的回答是正确的,但值得深入研究。您正在查看此接口定义:

UIView

而你假设这意味着这是一个强大的财产。它根本没有说。它说superview具有只读UIView.backgroundColor属性。没有setter,所以你不会指望任何内存管理注释(强/弱/无主)。

即使它有一个setter,例如var backgroundColor: UIColor? { get set }

UIColor

这告诉我们关于内存管理的一切。视图无法保留此UIColor。它可以自由制作自己的副本。它是CGColor中的免费提取信息,并为其内部使用生成一些其他对象(如backgroundColor),并抛弃它。没有承诺weak有一个支持ivar。这可以自由地成为计算机设定器。

某些属性(如委托)标记为weak var transitioningDelegate: UIViewControllerTransitioningDelegate? { get set }

class AnotherClass {
    deinit { print("deinit") }
}

class MyClass {
    private var _myProp: AnotherClass?
    weak var myProp: AnotherClass? {
        get { return _myProp }
        set { _myProp = newValue }
    }
}

您通常可以相信这些不会保留传递的对象,但请记住这些是信息,而不是保证。考虑这完全合法(并且完全可怕)Swift:

myProp

weak声称是UIView,但确实保留了其价值。你永远不应该这样做,但重点是语言不能阻止你。

所有这一切的消失是,如果你关心一个物体继续存在,你有责任保持对它的强烈引用。当你不在乎它是否存在时,你应该释放你对它的强烈引用。你应该避免依赖其他一些对象为你维护它。

(在实践中,有很多真实的案例,依赖于其他一些对象会为你提供一些东西这一事实非常方便。例如,我们当然很大程度上依赖于Arrays强烈引用它们的事实。但是,如果你需要它,你可以确定容器是否承诺这种行为。看看界面是不够的。)

对于- (UIView *)superview { UIView *result; if ([UIView _isAccessingModel] != 0x0) { id visualState = [self visualState]; result = [visualState mSuperview]; } else { if ([self viewFlags] & 0x400000)) { CALayer *superLayer = CALayerGetSuperlayer([self layer]); result = nil; if (superlayer != nil) { result = CALayerGetDelegate(layer); } } } return result; } 的具体问题,这是一个计算属性。虽然是一个实现细节,但这里大致是它在iOS 10.1中的实现方式:

{{1}}

答案 1 :(得分:6)

superview属性不一定是强属性,可以是其他私有弱属性的计算属性。

addSubview方法建立了从superview到子视图的强引用,而不一定是从子视图到superview。

在viewDidLoad方法结束时,view1不在视图hirarchy中,并且没有指向view1的任何其他对象,因此它被取消分配,但view2也有视图控制器指向它,因此view2不会被释放。

答案 2 :(得分:4)

  

UIView标头声明superview属性很强

根本没有说明。它声明的是属性是只读。您无法设置超级视图,因此甚至不会出现保留策略问题。您甚至不知道 a"超级视图参考"。所有你知道的是,你可以通过属性语法要求superview,你会被告知它是什么。如何在幕后完成并没有指定,你也不应该关心它。

话虽如此:显然一个观点没有强烈引用它的超级视图,因为如果它确实存在,那么就会有一个保留周期(因为superview拥有它的子视图,因此对它有强烈的参考)。