Swift,两个问题。 1) weak var 2) @IBOutlet 的 bang 运算符

Swift, two issues. 1) weak var 2) bang operator for @IBOutlet

每个:

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

  2. 为什么UILabel的末尾有个bang运算符。我知道这是必需的,我同意它,但现在才问。

提前致谢。

  1. Swift IBOutlet 默认是弱的(但其他属性默认是强的)。所以两者的写法是一样的。

关于弱和强的区别,你有更多的细节here

  1. 根据apple documentation

When you declare an outlet in Swift, you should make the type of the outlet an implicitly unwrapped optional (!). This way, you can let the storyboard connect the outlets at runtime, after initialization.

引用 IBOutlets 时使用 weak 是因为只要对象保留在其父视图中,就会对它进行强引用。参见 weak or strong for IBOutlets。 接下来,bang 运算符指示 IBOutlet 是一个显式展开的标签。有了bang运算符,就保证了对象一定存在,所以在引用的时候,直接这样引用就可以了:

someLabel.text = "some text"

但是,您可以将它们设为可选的 IBOutlets:

@IBOutlet weak var someLabel: UILabel?

但访问它们时必须使用?

someLabel?.text = "some text"

出口很弱,因为视图元素由视图(强烈)拥有。我认为你的视图控制器也有一个强引用在技术上是可以的,但不是必需的。

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

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

    相反,它应该由其父视图拥有,无论它在树中的任何位置(UIView.subviews 强烈发生)。 View Controller 强烈拥有它的 View Tree 的根(UIViewController.view)。 weak 显式声明一个非拥有引用,该引用可能在视图控制器生命周期的不同时刻变为 nil。

  2. 在这里,我会提供一种替代使用 ! 的方法:使用隐式展开的可选引用是一种危险的做法,它会削弱 Swift 提供给我们的工具。从 Xib 或 Storyboard 加载的 View Controller 在其生命周期中包括在创建之后和它的 View 加载之前的固定时间,其中 @IBOutlet 引用为 nil,每次。假设在那段时间没有人会对成员进行操作意味着不使用 Swift 语法和编译器的反馈对我们有利。

    此外,@IBOutlet 是一个强大的工具,可以在设计屏幕或视图时采用灵活、视觉集中的方法。常见的做法是让您的 View Controller 公开 @IBOutlets 它所有可用的信息,无论是否知道它将被使用,并在构建和迭代时单独决定实际连接和使用哪个Interface Builder 中的视图。

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

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