Swift転職なら=>【LevTech】
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大
↑クリックして拡大

頭痛が減ったので共有です!

rebuild.fmを応援しています!

HOME > willsetとdidsetでプロパティを監視

willsetとdidsetでプロパティを監視。意味あるのか???

クラスのプロパティにはWillsetとdidSetという監視用の関数があると聞いたのですが、用途は分かるにしても メリットとしてはどういうものなのかなと、getterやsetterと何が違うのか?うーん、と考えていました。調べていると海外のサイトでは同じように疑問にもつ質問があがっていました。 getとsetで同じことができるのでは?との私と同じスタンスです。解決されていましたので、順に説明していきます。

サンプル画像

参考:Swiftのプロパティ監視(willSet/didSet)の挙動について調べてみた
参考:Swift の変数やプロパティの値監視について
参考:swift willSet didSet and get set methods in a property
参考:What is the purpose of willSet and didSet in Swift?

調査してみた

以下のようなint型の変数があったとします、willsetとdidsetはgetterやsetterと同じことなのでは?との疑問です。


//didsetとwillsetを利用した場合
var HigeCnt_didsetAndwillset : Int = 0 {
    didSet {
        println (HigeCnt_didsetAndwillset)
    }
    willSet(newValue) {
    ..
    }
}
//従来のsetterとgetterを利用した場合
var HigeCnt_Normal: Int {
    get {
        return HigeCnt_Normal
    }
    set (newValue){
    }
}

上記は理解できます。

以下の方法ができるからwillsetとdidsetは違うんだ、らしいのですが、、、うーんいまいちわかっていません!


//http://stackoverflow.com/questions/24006234/what-is-the-purpose-of-willset-and-didset-in-swift
class Foo
{
    var propertyChangedListener : (Int, Int) -> Void = {
        println("The value of myProperty has changed from \($0) to \($1)")
    }

    var myProperty : Int = 0 {
        didSet { propertyChangedListener(oldValue, self.myProperty) }
    }
}

この上の処理がgetterとsetterにはできないようです。変数が変数を変更することかな?変更前データにアクセスすることでしょうか。

やってみた

上記に記載しましたが、oldValueにアクセスできること=自動で保存されていること、に旨味があるのかなと思いました。と思いましたが、 setterやgetterでもできますよね、うーん。ひとまず、上の変数から変数を呼び出す処理をgetterやsetterで書き換えられないものかやってみます。

一つわかったwillsetとdidsetのメリット


//willset と didset
class Foo
{
    var propertyChangedListener : (Int, Int) -> Void = {
        println("The value of myProperty has changed from \($0) to \($1)")
    }
    
    var myProperty : Int = 0 {
        didSet { propertyChangedListener(oldValue, self.myProperty) }
    }
}
//setterとgetter
class Foo2
{
    var propertyChangedListener : (Int, Int) -> Void = {
        println("The value of myProperty has changed from \($0) to \($1)")
    }
    
    var myProperty : Int {
        get {
            return self.myProperty
        }
        set (newValue){
            propertyChangedListener(self.myProperty, newValue);
        }
    }
}

この状態で以下を実行すると,,,,


    let foo:Foo = Foo();
    foo.myProperty = 1;
        
    let foo2:Foo2 = Foo2();
    foo2.myProperty = 2;//エラー

最初のwillsetとdidsetを利用する方法ならエラーが発生せず、0から1に変更されましたとログに表示。 foo2(getterとsetter)の場合は初期値がないのでエラー。setterやgetterを含める場合、初期値をセットすることはできない。init処理で セットしてあげないといけない。(参考URL:Set a default value for a property with defined getter and setter)

つまり、現状のすでに初期値もセットされているようなクラスに、この変数が変わった時に処理をいれたいな、、、、と思ったら、 現状のソースに影響させずにdidsetやwillsetを追加しやすい便利な関数なのかと腑に落ちました。他に利点があるのかもですが、ひとまずここまでにします。

まとめ

まとまらない状態で記事を書きすすめましたので支離滅裂してすいません、、、willsetとdidsetは私の考察では、 既存のクラスでなにかエラーが発生して、変数まわりが怪しいー>変数をwatchしてログ出力させたい時なんかに便利に利用できるのではと思いました。

↓こんな記事もありますよ!

Facebook SDK のAppEventを検証する

さて、AppEventですが、FacebookのAppを利用したログシステムなのかな。ログをカスタマイズして保存して、 それを解析できる、そんな感じなのかなと思っています。 広告利用の為に、インストールされた数やログの解析によってユーザの動作を確認できるようですので細かく設定できるのではと思います。 まずは上記のようにログを保存する、ログを読み込む、ができるのかを検証してみます

LawsonのWifiが6月1日からPCでも利用可能?+Wifi通信状態確認

店員さんに 聞くと「いままではアプリ経由でスマホだけだったんですが、パソコンでもいけるみたいですね〜」とあまり興味がない感じで 答えをいただいたのですが、僕の中ではショッキング。嬉しさで内心ソワソワしておりました。

アップルWatchから親アプリケーションへデータ送信

前回の記事では実機上で親アプリケーションからAppleWatchにイベントを送るのができなかった。 Notificationでできるはずなのですが、動作してくれなかった、、、、、。今回はいったん逆の時計から親アプリへのデータ送信の方法サンプルサイト をQiita様の中の記事でみつけましたので検証してみます。
このエントリーをはてなブックマークに追加
右側のFacebookのLikeをクリック頂けると記事更新の際に通知されますので宜しければご利用下さい!