为什么在 Swift 中使用 `weak` 进行初始化会返回 `nil`?

12

weak var的初始化为什么会返回nil,而通常的var的初始化则会返回预期的结果?在下面的ViewController.swift代码中:

weak var myButton: UIButton!
var myButtonNotWeak: UIButton!

override func viewDidLoad() {
    let frame = CGRect(x: 0, y: 0, width: 100, height: 100)
    myButton = UIButton(frame: frame)
    myButtonNotWeak = UIButton(frame: frame)
    print("\(myButton), \(myButtonNotWeak)")
}

这将以下内容记录到控制台:

nil, <UIButton: 0x7f946bc424a0; frame = (0 0; 100 100); opaque = NO; layer = <CALayer: 0x7f946bc42920>>

但为什么第一次返回nil?我认为如果你将一个变量定义为weak,那么当定义"弱引用变量"(self在这种情况下)的视图控制器消失时,"弱引用变量"也会随之消失。但我相信我在代码中没有删除ViewController的实例,也没有将其赋值为nil,特别是在其viewDidLoad()方法中。

所以如果我理解正确,为什么"弱引用变量"在初始化时返回nil?当我用@IBOutlet使用它时,它不会变成nil(尽管我不需要显式地初始化它)。那么当我想要在代码中初始化它时,特别是在viewDidLoad()中,我应该不使用weak来定义实例变量吗?

我希望在viewDidLoad()之外保留变量,因为我想在其他方法中引用该实例。在这种情况下,最好的方法是什么?


1
新分配的对象没有强引用,因此它会立即被释放,someObject 也会被设置为 nil。 - Dávid Kaszás
在Swift中有两种弱引用类型:weak和unowned。它们与Objective-C中的相同,但不同之处在于unowned引用永远不会是nil。 - gabbler
1个回答

17

weak 的意思是变量不会保留对象,如果没有其他强引用它将被释放。 @IBOutletweak 变量并不为 nil,因为这些视图在视图控制器的视图层次结构中有强引用。

在将按钮赋值给弱属性之前,您必须使用强引用引用它并将其添加到视图层次结构中,或者简单地不使用 weak 属性。


好奇的是,在什么情况下我需要使用weak?如果不会发生循环引用,似乎我应该始终使用strong。 - ikzjfr0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接