我基本上使用outlet作为弱变量,比如
@IBOutlet weak var testButton: UIButton!
但如果我使用强而不是弱,会发生什么,比如
@IBOutlet var testButton: UIButton!
使用后我是否必须将其设置为零?
答案 0 :(得分:5)
你得到了一些不好的答案。
奥特莱斯通常是弱的,和隐式解包的选项。这就是类型后的!
表示的内容。
出口被声明为弱,以避免在不再需要后将视图层次结构保留在内存中。 (通常情况下,出口是由它的超级视图所拥有的,只需从它的超级视图中删除它就会导致它被取消分配。通常这是正确的行为。如果你想要一个出口继续它的后面和&# #39; s从它的超级视图中移除你可以创建另一个强大的引用或使出口强大,但在这种情况下,当你完成它时,它取决于你)
奥特莱斯应该被宣布为弱,只有极少数例外。是的,如果你声明它们很强大,那么当你完成它们时你应该把它们弄清楚。 (虽然如果你的视图控制器被取消分配,那么它并不重要,因为它的强引用会消失。)
答案 1 :(得分:4)
只要它们在屏幕上作为子视图,就会很好。实际上,它们将由superView的subviews
数组保留。一旦它们从屏幕上移除(因此从subviews
阵列中移除),retainCount
将减少一个。如果出口的唯一强引用位于subviews
数组(弱属性情况)中,则retainCount
将为零,对象将被释放,并且您的testButton
属性将变为零。在这种情况下,您永远无法重用testButton
属性,因为它是强制解包的,任何访问都会导致崩溃。如果可以通过编程方式从屏幕中删除视图,那么将此属性设置为?
可选是一个好主意。
如果您希望以编程方式从屏幕上删除此插座,并希望此属性获得对插座的强引用,并依次根据某些用户交互逻辑以编程方式将其添加为子视图。在这种情况下,具有强引用的removeFromSuperView方法将减少仍为1的保留计数,因为您的属性保留了对象。
如果您将强引用设置为nil,并且该对象不再是子视图,那么它将被取消分配,并且您将无法重用testButton属性。
如果您设置为nil强引用,但对象仍然是视图层次结构中的子视图,那么它将保留在那里直到其superview被销毁,但您将永远无法再次操作该对象,作为您的参考对象已经消失了。
一般情况下,如果在你的程序逻辑中,属性在其范围内可以变为nil,则将其声明为?
可选而不是!
强制解包可选是更安全的,因为展开的力将会如果在他们为零时访问则导致崩溃。
我希望自己足够清楚,并且回答了你的怀疑。
修改强>
以编程方式创建视图;首先,没有可供参考的出口是一个好主意。如果一个新的开发人员进入你的项目并看到一个出口,他希望在xib或故事板上找到相应的插座;他不希望通过代码看到这个插座。
无论如何,我们必须注意一些情况。但是所有这些都依赖于同样的规则:
要更好地理解:
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定义为强大,可以解决问题。
以下情况不同:
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.
}