Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

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

きっかけ

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のSelfはProtocolを採用した具体的な型のメタタイプを指すことから、サブクラス名が返却されます。

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

使い所

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

おわりに

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

y_hakutaku
iOS Android Apps Engineer Objective-C, Swift, Android
openwork
転職・就職のための情報プラットフォーム「OpenWork」の企画・開発・運用をしています。
https://vorkers.jp/
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