UIView超级属性是弱还是强?
UIView标题指出,superview属性是强大的
open var superview: UIView? { get }
但它的行为就像一个弱的属性,即如果我创buildview1和view2,然后调用view1.addSubview(view2),然后保存强ref只view2(不view1),即使view2引用它view1将被定义通过其superview财产。
所以,我想知道它是如何实现的。
编辑 :例如,这个代码打印“deinit”(ViewController实例显示在屏幕上),这意味着view1
被定义,尽pipeview2
应该通过superview
属性强有力地持有它。
class View: UIView { deinit { print("deinit") } } class ViewController: UIViewController { var view2 = UIView() override func viewDidLoad() { super.viewDidLoad() let view1 = View() view1.addSubview(view2) } }
奥列格的回答是正确的,但值得深入挖掘。 你正在看这个接口定义:
open var superview: UIView? { get }
你认为这意味着这是一个强大的财产。 这根本就不说。 它说UIView
有一个只读的superview
属性。 没有setter,所以你不会期望任何内存pipe理注释(强/弱/无主)。
即使它有一个setter,例如, UIView.backgroundColor
:
var backgroundColor: UIColor? { get set }
这告诉我们内存pipe理完全没有。 没有承诺,这个UIColor
将被保留的观点。 它是自由制作自己的副本。 它是从UIColor
自由提取信息并生成其他内部使用的对象(如CGColor
),并将其扔掉。 没有承诺backgroundColor
拥有支持伊娃。 这是免费的计算器。
一些物业,如代表,标记为weak
:
weak var transitioningDelegate: UIViewControllerTransitioningDelegate? { get set }
您一般可以相信这些不会保留传递的对象,但请记住这些是信息性的 ,而不是保证。 想想这个完全合法的(而且完全可怕的)Swift:
class AnotherClass { deinit { print("deinit") } } class MyClass { private var _myProp: AnotherClass? weak var myProp: AnotherClass? { get { return _myProp } set { _myProp = newValue } } }
myProp
声称自己weak
但实际上保持其价值。 你不应该这样做,但重要的是,语言不会阻止你。
所有这一切的结果是,如果你关心一个对象继续存在,你有责任保持一个强有力的参考。 当你不在乎是否存在,你应该释放你的强烈的参考。 你应该避免依靠其他对象来维护它。
(在实践中,有很多真实的情况下,依赖于其他某个对象会为你保留某些东西的事实是非常方便的,例如,我们当然非常依赖于Arrays对它的内容有强烈的参考的事实。如果你需要的话,你可以肯定容器是有希望的,查看界面是不够的。)
对于UIView
的具体问题,这是一个计算属性。 虽然实现细节,这里大概是如何在iOS 10.1中实现的:
- (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; }
超级财富不一定是强大的财产,可以是其他私人财产的计算财产。
addSubview方法build立从superview到子视图的强引用,而不一定从子视图到superview。
在viewDidLoad方法view1不在视图hirarchy中,并没有任何其他指向view1的对象,所以它被取消分配,但view2也有指向它的视图控制器,所以view2不会被释放。
UIView标题指出,superview属性是强大的
它根本没有说明。 它所说的是属性是只读的 。 你不能设置超级视图,所以甚至不会出现保留策略的问题。 你甚至不知道是否有“superview参考”。 所有你知道的是,你可以通过属性语法的方式要求超级查看,你会被告知它是什么。 如何在幕后完成没有指定,你不应该关心它。
话虽如此:显然一个观点没有强调它的超级观点,因为如果真是这样的话,就会有一个保留周期(因为超级观点拥有它的子观点,因此有很强的参考性)。