在Swift中初始化时调用实例方法

我是新来的Swift,并想要使用像这样的实例方法初始化一个对象的成员variables:

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() } } 

基本上,我不是在init方法中内联所有的初始化代码,而是要将初始化代码y提取到专用方法createY并在init调用此实例方法createY 。 但是,Swift编译器(Xcode 6.3 beta中的Swift 1.2编译器)抱怨:

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

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

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

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

 init(x: String) { self.x = x super.init() self.y = createY() } 

任何意见表示赞赏。 谢谢。

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

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

然后通常从你的init调用它。

 class MyClass { let x: String let y: String init(x: String) { self.x = x self.y = createY(x) } } 

如这里所回答的那样,创build一个类函数。 我已经添加完整的代码。

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

我认为Swift的方法是使用Computed Properties( https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html

编辑

您可以使用计算属性来代替调用函数来修改set / get上的属性:

 class MyClass { var x: String? var y: String? { get { return "\(x!)_test" } } init(x: String!){ self.x = x } } let myClass = MyClass(x: "string") print(myClass.y!) #=> "string_test" 

在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" } } 

这里的秘密酱是使用private(set) lazy 。 这样,你可以给你的属性添加一个varlazy会延迟初始化,直到你的init函数完成之后。 使用private(set)只允许该类中的函数修改该属性,包括lazy关键字,但不允许公共接口更改它。 当然,如果你想让你的界面改变你的属性,那么你也可以将其标记为internal (默认)或public 。 但是你需要让它标记一个lazy var

你可以用这种方法

类MyClass:NSObject {

  let x: String var y: String init(x: String) { self.x = x self.y = self.x + "_test" print(self.x) print(self.y) } } 
 class MyClass { let x: String lazy var y : String = { return x + "_test" }() init(x: String) { self.x = x } }