我基本上用插座作为弱变量,比如
@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.
}