我基本上用插座作为弱变量,比如

@IBOutlet weak var testButton: UIButton!

但是如果我用强者代替弱者
@IBOutlet var testButton: UIButton!

使用后是否必须将其设置为零?

最佳答案

薄弱的出口是好的,只要他们在屏幕上作为子视图。事实上,它们将被超级视图的subviews数组保留。一旦将它们从屏幕上移除(因此从subviews数组中),则retainCount将减少一个。如果outlet的唯一强引用位于subviews数组中(弱属性情况),则retainCount将为零,对象将被释放,而您的testButton属性将变为零。在这种情况下,您将永远无法重用testButton属性,因为它是强制展开的,任何访问都将导致崩溃。如果视图可以通过编程方式从屏幕中删除,那么最好将此属性设置为?可选。
如果希望以编程方式从屏幕中删除此出口,并根据某些用户交互逻辑以编程方式将其重新添加为子视图,则需要此属性获取对该出口的强引用。在这种情况下,如果有一个强引用,removeFromSuperView方法将减少仍然为1的保留计数,因为您的属性将保留该对象。
如果将强引用设置为nil,并且对象不再是子视图,则将取消分配该对象,并且您将无法重用testButton属性。
如果将强引用设置为nil,但对象仍然是视图层次结构中的子视图,则该对象将保持在该视图中,直到其超视图被破坏,但当对该对象的引用消失时,您将无法再次操作该对象。
一般来说,如果在程序逻辑中某个属性在其作用域内可以变为nil,则更安全的做法是将其声明为?可选,而不是声明为!强制展开可选,因为当它们为nil时,如果访问强制展开将导致崩溃。
我希望我说得够清楚,我能回答你的疑问。
编辑:
以编程方式创建视图;首先,最好不要有可供参考的出口。如果一个新开发人员进入你的项目并看到一个出口,他希望在一个插件或一个故事板上找到相应的出口;他不会期望通过代码创建这个出口。
无论如何,这里我们必须注意一些案件。但他们都遵循同样的规则:
弱者不增加保留数,强者增加保留数。
retain count==0的对象立即被释放。
指向已解除分配实例的弱引用立即变为nil
为了更好地理解:

weak var testButton: UIButton!

func createButton() {
    testButton = UIButton()
    //Here testButton is already nil, because testButton is weak and
    //the new UIButton is not retained.
    view.addSubiew(testButton) //crash, because you are accessing
    //a nil force unwrapped property
}

在这里将tesButton定义为strong可以解决这个问题。
以下情况不同:
weak var testButton: UIButton!

func createButton() {
    let localTestButton = UIButton() //this is strong
    testButton = localTestButton //this is weak
    //here the new UIButton is retained by the localTestButton var
    //so its retainCount is 1, so testButton is not nil as its
    //reference is not deallocated
    view.addSubview(testButton) //all good, this retains the UIButton
    //that now has a retain count of 2
    //At the end of the scope, all the local var are released, and
    //their pointed objects decreases the retainCount.
    //in this scope there is just the localTestButton that is released
    //so the pointed object's retain count decreases from 2 to 1.
    //if in another scope the subview is removed (testButton.removeFromSuperView())
    //then the UIButton retain count is 0 and it is deallocated.
    //testButton will immediately become nil and no longer usable.
}

10-04 19:50