11
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Swiftで使う修飾子の順番(SwiftLintを参照して)

Posted at

はじめに

複数の修飾子のつくプロパティを書いているとき、

:thinking: 「dynamic と public と @objc ってどの順番にすべきなんだっけ?」

とか思っていたら、SwiftLintに参考になるものがあったので、まとめます。

結論(SwiftLintとしての推奨)

  • 推奨順序

    • [override, acl, setterACL, dynamic, mutators, lazy, final, required, convenience, typeMethods, owned]
@objc public private(set) dynamic weak var foo: Bar? 
public class Foo: Bar {
   override public final class var foo: String {
       return "bar"
   }
}

SwiftLintのルールの参照先

各修飾子の解説

ACL

  • Access Control Level のこと
    • open
    • public
    • internal(デフォルト)
    • fileprivate
    • private

setterACL

  • セッターに対応するゲッターよりも__低い__アクセスレベルを指定して、その変数、プロパティ、または添え字の読み取り/書き込みスコープを制限するために使うもの。
    • fileprivate(set)
    • private(set)
    • internal(set) など。
public struct TrackedString {
    public private(set) var numberOfEdits = 0
    public var value: String = "" {
        didSet {
            numberOfEdits += 1
        }
    }
    public init() {}
}

dynamic

  • Objective-Cのランタイムを用いるために使う。@objc を使うときにはdynamicキーワードが必要。
  • RealmSwiftを使うときには頻出。

mutators

  • 多分mutating キーワードのこと。
  • Swiftでは、特に要求しない限り、プロパティを変更するメソッドを記述できない。
  • メソッドの中でプロパティを変更したいときは、mutating キーワードを使ってマークする必要がある。
struct Person {
  var name: String
  mutating func makeAnonymous() {
      name = "Anonymous"
	}
}
  • 呼び出し方
var person = Person(name: "Ed")
person.makeAnonymous()

lazy

  • 参照された時に初めて初期値が設定されるプロパティ。
  • 不要なメモリの消費やパフォーマンスの低下を防ぐことができる。
  • ただ、もし使うときは気を付ける。いくつか記事見ていると、安易に使うと不具合の元な感じが伝わってきた。

便利なlazyですが、
初期化タイミングが不明瞭なため思わぬバグを引き起こすことがあります。

私見ではありますが、
プロジェクト内での利用タイミングの統一やコメントでの補足等しておく必要はあるかと思います。

参照先 【Swift4.1】lazyプロパティの使い所


lazyなプロパティは
不要なメモリの消費やパフォーマンスの低下を防ぐことができますが
使い方を誤ると
わかりづらい不具合を混ぜてしまう可能性があることがわかりました。

参照先 【Swift】Lazyプロパティの使い方に気をつける(ドキュメントの確認は大事)

final

  • override を防ぐ。

  • メソッド、プロパティ、subscript(添え字?)が override されることを防ぐ。

    • final var
    • final func
    • final class func
    • final subscript
  • クラスが継承されることを防ぐ。サブクラス化しようとすると、コンパイル時エラーになる。

    • final class

required

  • クラスの初期化子の前につけて、クラスの全てのサブクラスがその初期化子を実装する必要があることを示す。
class SomeClass {
    required init() {
        // initializer implementation goes here
    }
}

class SomeSubclass: SomeClass {
    required init() {
        // subclass implementation of the required initializer goes here
    }
}

convenience

  • クラスの初期化子をサポートする。指定した初期化子を呼び出し、その初期化子のパラメーターの一部をデフォルト値に設定できる。
class Food {
    var name: String
    init(name: String) {
        self.name = name
    }
    convenience init() {
        self.init(name: "[Unnamed]")
    }
}

typemethod

class SomeClass {
    class func someTypeMethod() {
        // type method implementation goes here
    }
}
SomeClass.someTypeMethod()

owned

  • unowned
  • weak

参考サイト

11
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?