yashigani?.days

週刊少年ジャンプについてだらだら書きます

SwiftのPropertyでObjective-Cのアレがしたい

overrideする

Objective-CではPropertyはただのアクセサメソッドの自動生成だったので,overrideするのはなにも考えなくてもいいって感じだったけど,Swiftでは微妙に違う. 例えばUIScrollViewcontentInsetをいじって常に上部にマージンを設けたいときはこうする.

class MyScrollView: UIScrollView {
    private let topMargin: CGFloat = 44
    override var contentInset: UIEdgeInsets {
        get {
            return super.contentInset
        }
        set(newInset) {
            var inset = newInset
            inset.top = topMargin
            super.contentInset = inset
        }
    }
}

Propertyを再定義する感じだった. getterではなにもせずにsuper.contentInsetを返して,setterでは新しい値のtopをいじってからsuperclassのsetterを呼んだ. newInset.topを直接いじれたら楽だったけどできなかった. 理由はよくわからない.

Property名と実際の変数名を分ける

Objective-Cでは以下のようにPropertyと実変数を分けるのもよく見かけるパターンだ.

@interface Animal : NSObject
@property (nonatomic, copy) NSString *name;
@end

@implementation Animal {
    NSString *_name;
}
@synthesize name = _name;
@end

Swiftでやるならこう.

class Animal {
    private var _name: String = ""
    internal var name: String {
        get {
            return _name
        }
        set(newName) {
            _name = newName
        }
    }
}

Objective-Cよりは普通.

まとめ

Objective-Cでできたアレはどうやるんかな?って考えながら書くと楽しい.