Swift两个问题:1)weak var 2)@IBOutlet的感叹号运算符

22

Per:

@IBOutlet weak var nameLabel: UILabel!
  1. 每当我声明IBOutlets时,我只使用var而不是weak var。但最近我遇到了一些代码模板,它们使用weak var。他们为什么这样做?有什么附加的好处吗?

  2. 为什么在UILabel的末尾有一个bang运算符。我知道它是必需的,我会用它,但现在想问一下。

谢谢事先。


如果这是两个问题,我会投票将其关闭为在ARC下,IBOutlets应该是强引用还是弱引用?在Swift语言中感叹号的含义是什么?的重复。 - Matthias Bauch
如果您将插座拖入源中,则这是Xcode的默认行为。我不明白为什么它被明确称为“弱引用”,或者在运行时忘记连接IBOutlet时会发生什么,但也许因为您手动完成了它,Apple希望您始终设置它。 - Lucas van Dongen
4个回答

25
  1. Swift的IBOutlet默认为弱引用(但其他属性默认为强引用)。因此,这两种写法是相同的。

关于弱引用和强引用之间的区别,您可以在这里找到更多详细信息。

  1. 根据苹果文档

当您在Swift中声明outlet时,应将outlet的类型设为隐式解包的可选类型(!)。这样,您就可以在初始化后让storyboard在运行时连接outlet。


12

因为视图元素是由视图(强烈)拥有的,所以出口较弱。我认为你的视图控制器也可以有一个强引用,但没有必要。

弱变量是可选的,因为它们可以是nil。你可以用?声明你的输出口,但这意味着每次都使用强制解包或可选绑定。将它们声明为隐式展开的可选项!只是一种方便。


简洁明了 - Shaik Riyaz

1
当涉及IBOutlets时,您使用weak这个词,因为只要对象仍在其superview中,就会有一个strong引用指向它。请参阅IBOutlets的weak还是strong。 接下来,感叹号运算符表示IBOutlet是一个明确展开的标签。通过感叹号运算符,它保证该对象将存在,因此在引用它时,您可以像这样简单地引用它:
someLabel.text = "some text"

然而,您可以将它们的IBOutlets设为可选项:
@IBOutlet weak var someLabel: UILabel?

但是当访问它们时,您必须使用
someLabel?.text = "some text"

1
隐式解包可选项不能保证不为 nil。然而,当 viewDidLoad 被调用时,@IBOutlets 将被初始化。 - Petter
@Petter,@IBOutlets在控制器的awakeFromNib被调用之前就已经被初始化了。 - BangOperator

1
  1. @gregheo的回答是最好的解释,进一步阐述:在这种情况下,如果考虑所有权,由@IBOutlet引用的View对象通常不应该由引用它的View Controller拥有。

    相反,它应该由其父视图拥有,无论它在树中的位置如何(可以通过UIView.subviews强烈拥有)。View Controller强烈拥有它的View Tree的根(UIViewController.view)。 weak明确声明了一个非拥有引用,在View Controller的生命周期的不同点可能变为nil。

  2. 在这里,我提供使用隐式展开可选引用的替代方法:!是一种危险的做法,会削弱Swift提供给我们的工具。从Xib或Storyboard加载的View Controller在创建后和View加载之前的时间内,@IBOutlet引用始终为nil,每次都是如此。假设在那段时间里没有人操作成员意味着没有使用Swift语法和编译器的反馈来帮助我们。

    此外,@IBOutlet是一种强大的工具,可以在设计屏幕或视图时实现灵活、视觉化的方法。通常,您的View Controller会为所有可用信息公开@IBOutlet,无论是否已知将使用它们,并在从Interface Builder内部构建和迭代View时分别决定实际连接和使用哪些。

    此外,如果您的View应该足够灵活,可以从Xib/Storyboard和代码中实例化,那么根据您决定引用的子视图如何实例化和连接,它们可能立即可用或不可用。

由于上述原因,我定义了我的:@IBOutlet weak var nameLabel: UILabel?

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