LoginSignup
2

More than 1 year has passed since last update.

posted at

updated at

Organization

クラス名を取得する便利な方法

きっかけ

ViewController名をインスタンスに依存せずに取得、また定義も一箇所にまとめられないかと考えていました。

親クラスのstatic propety

当然ながらSuperと出力される

class Super {
    static var name: String {
        String(describing: self)
    }
}

class Sub: Super {

}

print(Super.name)
print(Sub.name)

出力

Super
Super

protocol extensionをつかって実現する

class Super: NameConvertible {

}

class Sub: Super {

}

protocol NameConvertible {
    static var name: String { get }
}

extension NameConvertible {
    static var name: String {
        String(describing: Self.self)
    }
}

print(Super.name)
print(Sub.name)

出力

Super
Sub

なぜこのような動きになるのか

ProtocolのSelfはProtocolを採用した具体的な型そのものを指すという言語仕様がキーになります。
つまりSelf.selfは
Protocolを採用した具体的な型のメタタイプを指すことから、サブクラス名が返却されます。

extension NameConvertible {
    static var name: String {
        String(describing: Self.self)
    }
}

使い所

  • UITableViewCellなどに適用し、identifierの宣言を簡略化させたいとき。
  • エラーメッセージやロギング向けにクラス名をインスタンスに依存せず取得し、かつ各クラスで実装せずに済ませたいとき。

おわりに

staticなpropertyだけど継承が影響する少し不思議にも感じる動きですが、理由を理解すると便利です。
protocol extensionなので、UIKitのクラスなどに適用できるのがポイントかと思います。
とはいえ、今回のような本来静的な値をするくらいの、シンプルな利用くらいが良さそうです。

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
What you can do with signing up
2