115
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

[Swift] Property のベストプラクティスを考える

これはなに

Swift には Property という機能があります。それにより setter/getter が手軽に書けるようになりました。
どのようにしたら可読性に優れ、簡潔になるかを考えてみたという記事です。

Property とは

公式ドキュメント:https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html
Swift は相変わらず公式ドキュメントが読みやすくてよいですね。

Objective-C でも property はありましたね。プロパティ宣言をよくしていたと思います。

Objective-C
@interface Hoge: NSObject {
    NSString *_string = @"";
}
@property (nonatomic, strong, getter = getString, setter = setString:) NSString *string;
@end

@implementation Hoge: NSObject
- (NSString*) getString {
    return _string;
}

- (void) setString: (NSString*) newValue {
    _string = newValue;
}
@end

まあここまで明示的に書くことはなかなかないですが、Objective-C ではプロパティ宣言で getter/setter を指定していました。
読み取り専用の場合は readonly をつけたりしましたね。

全く同じものは、Swift では以下のように書くことができます。

Swift
class Hoge {
    var _string = ""
    var string: String {
        get {
            return _string
        }
        set {
            _string = newValue
        }
    }
}

まあこれだと、「なんだかカッコつけたようになったな」という感想があると思います。

それって、これで済むよね

Swift
class Hoge {
    var string = ""
}

Objective-C のプロパティ宣言で getter/setter の記述を省略できるのと同じように、 getter/setter で代入、取り出し以外の操作をしないならば プロパティを使う必要はないと思います。

プロパティを使いたい場面

  • setter にもう一手間加えたい

例えば、代入されたらそれを NSUserDefaults に保存したいとき。

Swift
class Hoge {
    var _string = ""
    var string: String {
        get {
            return _string
        }
        set {
            _string = newValue
            NSUserDefaults.standardUserDefaults().setObject(newValue, forKey: "string")
        }
    }
}

おお、これだとわざわざ setter を書いた意味がありそう。

でもそれって、これで済むよね(二回目)

Swift
class Hoge {
    var string: String = "" {
        didSet {
            NSUserDefaults.standardUserDefaults().setObject(string, forKey: "string")
        }
    }
}

Property には、 didSet, willSet というセット直後・直前に呼ばれる場所を定義することができます。
だから、 setter に一手間ならば didSet, willSet でやればいいですね。

getter/setter を本当に使いたいケース

readonly な変数

Swift
class Hoge {
    var string: String {
        get {
            return "hoge"
        }
    }
}

このように、getter のみを記述すればその変数は readonly となります。
この記法だとカッコが多いので、以下のように省略できます。また GitHubのスタイルガイド で可読性とコード行数の観点から省略形が推奨されています。

Swift
class Hoge {
    var string: String {
        return "hoge"
    }
}

他の変数と組み合わせて使う

Swift
class Rect {
    var width: Float = 0
    var height: Float = 0
    var area: Float {
        return width * height
    }
}

この場合は area はクラスの他の2変数から常にかけ算の結果を返します。また、readonly なので安心です。

まとめ

Swift の Property は Objective-C のそれと比べ読みやすく、わかりやすくなっていると感じます。
また複数の方法で同じ処理を実現することができます。
なので、いつも同じ書き方、ではなく状況に応じて最も読みやすく、簡潔な書き方を心がけていきたいものです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
115
Help us understand the problem. What are the problem?