【问题标题】:Why are the outlets by default declared as weak?为什么出口默认声明为弱?
【发布时间】:2020-06-25 15:48:04
【问题描述】:

我在 google 上查找了这个主题,但还没有一个可以理解的答案,问题是我知道当两个类通过从第二个类实例化第一个类中的一个对象并在第一类的第二类,这将导致一个保留循环,应该通过使用关键字weak or unowned 来打破该循环,但我不能将这种思维方式应用于被声明为弱的 IBOutlets 例如

class SignUpViewController: UIViewController {
 override func viewDidLoad() {
        super.viewDidLoad()
    }
@IBOutlet weak var signUpBttn: UIButton!
}

这是我的 viewController 类中的一个出口,为什么出口被声明为弱?据我了解,为了有一个保留周期,uibutton 类应该有一个来自 viewController 类的对象,以便两个类(viewController 和 uibutton)耦合在一起 任何人都可以澄清幕后发生的事情吗?

【问题讨论】:

  • 这是讨论here
  • @ReinhardMänner 我看到了这篇文章,但整个事情对我来说仍然很模糊:S
  • Outlets 没有“默认”声明为弱,所以问题的整个前提是错误的。
  • 然而,一种思路可能会运行:视图控制器对其视图有一个强引用。该视图对其子视图有很强的引用。我们真的需要从视图控制器到子视图的另一个强引用吗?谁拥有子视图?它的超级视图。

标签: ios swift memory-management


【解决方案1】:

视图控制器中的所有 ui 元素都是 viewController 视图的一部分。所以 view 是一个 UIView 类,而 outlet 在 vi​​ewController 中是对 UIView 类元素的引用,所以如果从视图层次结构中删除视图,所有交叉元素都应该是弱的以避免交叉引用。与此有关的问题是来自苹果 MVC 的参考,其中 ViewController 是一个控制器,但有一堆与视图部分相关的代码。你所有的出口都应该放在你的 ViewController 的 UIView 类中。

【讨论】:

    【解决方案2】:

    TLDR - 在我看来,这不是一个好的决定。

    strong 引用表示所有权。视图或视图控制器是视图的所有者,因此逻辑选择应该是strong

    但是,在大多数情况下,这并不重要,因为视图也被视图层次结构中的父级强烈引用。

    什么时候重要?当您通过删除视图/约束等来动态更新视图层次结构时,这很重要。一旦从层次结构中删除视图/约束并且您没有对它的强引用,它将从内存中删除。

    还要注意weak! 的组合有点危险,因为! 表示您希望永远不会是nil 的引用。

    这可能会导致错误,例如:

    @IBOutlet weak var constraint: NSLayoutConstraint!
    
    ...
    
    constraint.isActive = false // removes constraint from hierarchy, assigns `nil` to constraint
    ...
    constraint.isActive = true // crashes the app
    

    就我个人而言,我总是制作网点strong。对于任何weak 引用,我总是使用? 而不是!

    请注意,在这种情况下,weak 与针对引用循环的保护没有任何关系。这只是 Xcode 开发人员的个人决定。

    从历史上看,可能与UIViewController.viewDidUnload 有联系。但是,自 iOS 6 以来,该方法从未被调用过。

    【讨论】:

      【解决方案3】:

      Apple 建议将@IBOutlet 声明为strong。可以找到许多关于此的讨论/文章。

      如果您观看 Apple 的 2015 WWDC 中的这段视频,就在 32:30 左右:https://developer.apple.com/videos/play/wwdc2015/407/

      他说:

      一般来说,你应该使你的出口变得强大,尤其是当你将出口连接到子视图或视图层次结构并不总是保留的约束时。唯一真正需要使出口变弱的情况是,如果您有一个自定义视图引用了视图层次结构的备份,通常不建议这样做。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-30
        • 1970-01-01
        相关资源
        最近更新 更多