メソッドをオーバーライドするときは、このメソッドのスーパー実装を呼び出す必要があります。
required override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
定let
数値は初期化子でのみ設定できます。複数の初期化子がある場合は、それらを連鎖させる方法を考えてください。1 つの指定された初期化子と多くの便利さがあると便利です。このようにして、変数を 1 か所だけに設定します。例
class A {
let age: Int
let name: String
let type: String
init(age: Int, name: String, type: String) {
self.age = age
self.type = type
self.name = name
}
convenience init() {
self.init(age: 0, name: "", type: "")
}
convenience init(age: Int) {
self.init(age: age, name: "", type: "")
}
convenience init(age: Int, name: String) {
self.init(age: age, name: name, type: "")
}
Swift では、init メソッドでクラスを完全に初期化する必要があります。これは、すべてのプロパティに値を設定し、存在する場合は super init を呼び出す必要があることを意味します。その後、自分自身にアクセスしてメソッドを呼び出すことができます。
Cocoa フレームワークでは、クラスをインスタンス化する方法が 1 つ以上あり、多くの初期化子があります。例 UIViewController には
init(nibName: String?, bundle: NSBundle?)
、init(coder :NSCoder)
このクラスをどのように初期化しますか?
- 変数の値を設定する
このソリューションには 1 つの大きな欠点があります。DRY
ではありません
。2 つの場所に同じコードがあります。変更または修正する必要がある場合は、2 か所で同じ操作を行う必要があります。本当に悪いアーキテクチャとコードの匂い。
var name: String
required init(coder aDecoder: NSCoder) {
name = "Name"
super.init(coder: aDecoder)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
name = "Name"
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
もっとうまくやれるでしょうか?解決策は明白に見えます-別の方法で名前の初期化を抽出します。しかし、 Swift クラスの安全規則の初期化ステップのため、それはできません。
- すべてのプロパティを設定する
- super.init(...) を呼び出す
- これで、クラスとスーパー クラスの両方が完全に初期化されました。ここでのみ、自分自身にアクセスして自分自身のメソッドを呼び出すことができます
コード:
required init(coder aDecoder: NSCoder) {
setDefaultName() // Error. Can't access self yet
super.init(coder: aDecoder)
}
func setDefaultName() {
name = "Name"
}
- デフォルト値
変数のデフォルト値を設定します。
プロパティを 1 か所だけで初期化するため、これは見栄えがよくなります。
var name: String = ""
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
変数を初期化するためにより複雑なロジックが必要な場合は、そのためにクロージャーを使用できます。
クラス変数宣言にロジック(関数と同じクロージャー)があるため、私はそれが好きではありません。
もっとうまくやれるでしょうか?はい、できます!
var name: String = {
var name = "Name"
// ....
// Other complicated logic
name + " Is Best"
return name
}()
- ファクトリ メソッド
そのクロージャーをクラス変数定義の外に移動する方が良い
ので、そのようなことができますvar name = Factory.defaultName()
Swift は内部クラスをサポートします。クラスの中にクラスを作成できます。このようにして、クラス内でいくつかの機能をグループ化できます。これは、初期化メソッドを Factory クラスにグループ化するのに最適なサウンド
です 最終的な例:
var name: String = Factory.defaultName()
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
class Factory {
class func defaultName () -> String {
return "Name"
}
}