swift - 将 self 作为参数传递给方法

标签 swift

当我们将一个对象的实例作为参数传递给一个方法时,该方法是在该对象内部定义的,如下面的代码所示,它会创建一个保留循环吗?

 self.someMethod(self)

最佳答案

如果您引用类的实例方法:

class FooBar {
  func foo() {
    print("Foo")
  }
  func bar() {
    self.foo()
  }
}

“self”是隐含的,编译器不需要它。即使您在没有 self. 的情况下使用 foo(),它仍然会隐式引用 self。

不,没有保留周期,因为您是在同一对象上从一个实例方法调用另一个实例方法。

编辑:

self 给您带来麻烦的地方在于“转义”闭包。转义闭包是传递给另一个对象的闭包,该对象对其进行强引用。完成处理程序通常会转义闭包。

因此,当您调用一个接受完成处理程序的函数并且该完成处理程序是一个转义闭包时,另一个对象将获得闭包的所有权。

现在,如果闭包使用 self,则意味着闭包也拥有“self”

typealias completionHandler = () -> ()

class AClass {
  lazy var someOtherObject = SomeOtherObject()
  var value: Int = 0
  func callClosure() {
      someOtherObject.doSomething(completion: {
          self.foo = self.foo + 1
      }
  }
}

class SomeOtherObject {
    var myCompletionHandler: () -> ()
    func doSomething( completion: @escaping completionHandler) {
       myCompletionHandler = completion
       //pretend there is code here to call an async method and invoke completion
    }
}

上面对 self 的使用确实导致了一个保留周期。方法如下:

AClass 的实例创建一个类型为 SomeOtherObject 的对象,并保持对它的强/拥有引用。只要 AClass 的实例存在,SomeOtherObject 就不会消失。

当我们调用callClosure() 时,我们传入一个完成处理程序。 SomeOtherObject 取得闭包的所有权。

现在,由于闭包的代码引用了 self,因此闭包获得了 self 的所有权。我们现在在拥有 SomeOtherObject 的 AClass 对象、拥有闭包的 SomeOtherObject 和拥有 的闭包之间有一个三向保留循环>AClass 对象。

您可以通过向闭包添加“捕获列表”来修复保留周期。这是闭包使用的变量列表,应该保持弱。修改后的代码可能如下所示:

func callClosure() {
  //the `[weak self]` capture list below makes self weak inside the closure
  someOtherObject.doSomething(completion: { [weak self] in  
      ///use a guard to map weakSelf to strongSelf if it isn't nil, or return
      //if self has been deallocated and is now nil.
      guard let strongSelf = weakSelf else { return }
      strongSelf.foo = strongSelf.foo + 1
  }
}

关于swift - 将 self 作为参数传递给方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49633208/

相关文章:

ios - 执行 CMSampleBuffer OpenGL Swift 的平移/旋转

swift - Swift 中的无符号右移运算符 '>>>'

ios - swift uitableview 重新排序除最后一个单元格之外的单元格

ios - 正则表达式在 Swift 中获取方括号对之间的文本

ios - 如何在具有自动布局的 Interface Builder 中创建的现有 View 中添加 View ?

swift - ld : framework not found Crashlytics Xcode7. 2.1

iOS 应用程序 OTA 安装失败,并出现错误 Domain=MIInstallerErrorDomain Code=11 Bundle 缺少或无效 CFBundleExecutable

ios - 快速定位中心 UICollectionViewCell

ios - ld : framework not found FirebaseNanoPB

ios - 无法快速使用 FMDB 加载数据库