読者です 読者をやめる 読者になる 読者になる

しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

SwiftのStored PropertyとComputed Propertyについて整理する

Stored PropertyComputed Propertyをちゃんと調べた事がなかったので調査してみました。

Stored Property

下のようなプロパティーです。

class MyClass {
    let prop1 = ""
    var prop2 = ""
}

プロパティー監視

Stored PropertyにはwillSetdidSetのプロパティー監視を使う事ができます。
それぞれ、newValueoldValueという変数を利用する事ができます。

class MyClass {
    var prop1 = "value" {
        willSet {
            print(newValue)
        }
        didSet {
            print(oldValue)
        }
    }
}

letで宣言したimmutableな変数は値が変わらないのでプロパティー監視は使えません。

class MyClass {
    let prop1 = "value" { // → これはエラー
        willSet {}
        didSet {}
    }
}

lazy

lazyという修飾子をつければプロパティーを使う時に初期値のセットをする事ができます。
複数UIViewControllerを保持する場合などのパフォーマンス向上に役立ちそうです。

class MyClass {
    lazy var vc1 = UIViewController()
    lazy var vc2 = UIViewController()
}

ちなみに宣言時はmutable(var)にする必要があります。

class MyClass {
    lazy let vc1 = UIViewController() // → letで宣言するとエラー
}

プロパティー監視は使えなくなります。

class MyClass {
    lazy let vc1 = UIViewController() {
        willSet {} // → エラーになる
        didSet {}
    }
}

それと初期値で文字列を使っているとエラーになるようです。

class MyClass {
    // 下2つはエラー
    lazy var prop1 = ""
    lazy var prop2 = NSURL(string: "")
}

構造体

構造体も同じようにプロパティーを使えます。

struct MyStruct {
    lazy var prop1 = NSDate()
    var prop2 = NSDate() {
        willSet { print(newValue) }
        didSet  { print(oldValue) }
    }
}

Computed Property

Computed Propertyは下のように自分でgetter/setterを実装するものです。
セットされた値はnewValueという変数に入っています。

宣言はmutable(var)にする必要があります。

class MyClass {
    var prop1: NSDate {
        get { return NSDate() }
        set { print(newValue) }
    }
}

プロパティー監視(willSet/didSet)は使えません。

// これはエラーになる
class MyClass {
    var prop1: NSDate? {
        get { return NSDate() }
        set { print(newValue) }
        willSet {  }
        didSet  {  }
    }
}

lazyも使う事ができません。

// これもエラー
class MyClass {
    lazy var prop1: NSDate? {
        get { return NSDate() }
        set { print(newValue) }
    }
}

getだけ実装すればreadonlyなプロパティーになります。

class MyClass {
    var prop1: NSDate? {
        get { return NSDate() }
    }
}

MyClass().prop1 = NSDate() // → これはエラー

readonlyな場合はgetを省略できます。

class MyClass {
    var prop1: NSDate? {
        return NSDate()
    }
}

セットだけのプロパティーを作る事はできません。

class MyClass {
    var prop1: NSDate? {
        set {} // → エラー
    }
}

構造体でも全く同じように使えます。

struct MyStruct {
    var prop1: NSDate? {
        get { return nil }
        set { print(newValue) }
    }
}

参考URL

Swift ストアドプロパティ(Stored Property) コンピューテッド・プロパティ(Computed Property) - Codable Tech Blog

The Swift Programming Language (Swift 2): Properties