【问题标题】:I find myself using "if self != nil" a lot because of [weak self] ...is this normal?我发现自己经常使用“if self!= nil”,因为 [weak self] ...这正常吗?
【发布时间】:2016-04-20 03:58:16
【问题描述】:

示例(在我的视图控制器中):

RESTApi.fetchUser() { [weak self] Void in 
    if self != nil { //the view controller is still here.
        self!.items.append(stuff)
        self!.whatever

    }
}

我注意到我立即使用if self != nil,然后到处使用self!。有没有更好的办法?我觉得这违反了 Swift 的方式。

注意:我使用 [weak self] 因为我的 ViewController 可能为零(如果用户在 REST Api 下载数据之前返回)。

【问题讨论】:

  • 不会自己被捕获,所以如果用户在 REST API 完成之前返回也没关系?
  • 我不确定。当涉及到 ViewControllers 时,我总是使用 [weak self]。其他人可以对此发表评论吗?
  • 这似乎是一种常见的模式。我认为如果你不让它变弱,被捕获的自我可能会引入一个引用循环并搞乱内存管理。

标签: swift


【解决方案1】:

你为什么不用if let

if let unwrappedSelf = self {
    unwrappedSelf.items.append(stuff)
    ...
}

你也可以使用guard let:

guard let unwrappedSelf = self else { return }

unwrappedSelf.items.append(stuff)
...

【讨论】:

  • 谢谢,这很酷。我的方式和你的方式有区别吗?
  • if let 更惯用。摆脱!。你也可以guard let else return
  • @TIMEX Thilo 是正确的。我会将guard 添加到我的答案中。
  • weakSelf 不是一个好名字,因为它是一个强引用。
【解决方案2】:

空闲你必须使用guard,它比if更空闲

guard let strongSelf = self else { return }

strongSelf.items.append(stuff)

【讨论】:

    【解决方案3】:

    如果您只是在调用闭包时调用self 上的方法,那么您甚至不需要使用if letguard letif self != nil。如果self 不为零,则下面的代码也可以很好地调用方法,如果是,则什么也不做:

    RESTApi.fetchUser() { [weak self] in 
        self?.items.append(stuff)
        self?.whatever()
    }
    

    除了需要将selfself 的属性作为参数传递给非可选函数参数或分配self 或@987654330 的属性的情况外,此条件展开可用于所有情况@ 指向具有非可选类型的变量。

    作为更广泛的说明,无论如何都不一定需要在这种情况下使 self 变弱。这通常只有在self 保留引用self 内部作为ivar(循环引用)的闭包时才需要。在您的情况下,RestApi 持有对闭包的引用,self 所指的视图控制器将由闭包保留,直到闭包返回。此时,如果视图控制器已经被用户解除,并且闭包的引用是对它的最后一个引用,那么它将在闭包执行后被释放(没有循环引用)。

    因此,在此示例中使 self 变弱仅适用于您特别希望解除视图控制器以解除分配实例和闭包的场景,然后根本无法运行任何东西。

    【讨论】:

    • 公平点,但是当视图控制器为 nil 时弱引用仍然有意义,处理获取的结果没有意义。 (假设获取的结果仅用于在视图控制器中显示)
    【解决方案4】:

    只需这样做:

       guard let `self` = self else {
           return
       }
       self.items.append(stuff)
    

    【讨论】:

      猜你喜欢
      • 2015-07-02
      • 2019-10-15
      • 2017-01-09
      • 1970-01-01
      • 1970-01-01
      • 2015-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多