在Swift初始化期间调用实例方法

nyb*_*bon 14 constructor initialization ios swift

我是Swift的新手,想要使用像这样的实例方法初始化对象的成员变量:

class MyClass {
  var x: String
  var y: String

  func createY() -> String {
    self.y = self.x + "_test" // this computation could be much more complex
  }

  init(x: String) {
    self.x = x
    self.y = self.createY()
  }     
}
Run Code Online (Sandbox Code Playgroud)

基本上,而不是内联所有的初始化代码init的方法,我想的初始化代码提取y到一个专门的方法createY,并调用这个实例方法createYinit.但是,Swift编译器(Xcode 6.3 beta中的Swift 1.2编译器)抱怨:

在super.init初始化self之前,在方法调用'xxx'中使用'self'

这里'xxx'是实例方法(createY)的名称.

我可以理解Swift编译器正在抱怨什么以及它想要解决的潜在问题.但是,我不知道如何解决它.什么应该是Swift中调用初始化代码的其他实例方法的正确方法init

目前,我使用以下技巧作为解决方法,但我不认为这是解决这个问题的惯用方法(这个解决方法需要y声明使用var而不是let让我感到不安):

init(x: String) {
  self.x = x
  super.init()
  self.y = createY()
} 
Run Code Online (Sandbox Code Playgroud)

任何评论表示赞赏.谢谢.

Joh*_*pia 12

转换createY()为接受x作为参数并返回a 的全局或类函数y.

func createY(x: String) -> String {
    return x + "_test" // this computation could be much more complex
}
Run Code Online (Sandbox Code Playgroud)

然后从您的电话中正常调用它init.

class MyClass {
  let x: String
  let y: String

  init(x: String) {
    self.x = x
    self.y = createY(x)
  }     
}
Run Code Online (Sandbox Code Playgroud)


cas*_*ora 6

在 Swift 3 中,我一直在使用这种模式,

class MyClass {
  var x: String?
  private(set) lazy var y: String? = self.createY()

  init(x: String){ self.x = x }

  private func createY() -> String?
  {
    return "\(x ?? "nil") test"
  }
}
Run Code Online (Sandbox Code Playgroud)

这里的秘诀是使用private(set) lazy. 这样,您就可以将您的财产标记为var. 并将lazy延迟初始化,直到您的init函数完成之后。使用private(set)仅允许此类内的函数修改该属性(包括lazy关键字),但不允许公共接口更改它。当然,如果你想让你的界面改变你的属性,那么你也可以标记它internal(默认)或public. 但你需要将其标记为lazy var