4
2

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.

SwiftAdvent Calendar 2020

Day 3

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

Last updated at Posted at 2020-12-02

きっかけ

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

親クラスのstatic propety

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

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

class Sub: Super {
    
}

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

出力

Super
Super

protocol extensionをつかって実現する

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

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

使い所

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

おわりに

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

4
2
2

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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?