isとisMemberOfClassとisKindOfClassですが、挙動の差がわかりにくかったのでまとめてみました。
isKindOfClass
下のようなケースでは当然trueになります。
それとisKindOfClass/isMemberOfClassはNSObjectProtocolのメソッドなので、NSObjectなどを継承しているクラスでのみ使えます。
class MyClass: NSObject {} let myClass = MyClass() print(myClass.isKind(of: MyClass.self)) // → true
isKindOfClassは判定対象が引数のサブクラスの場合もtrueになります。
class MyClass: NSObject {} class MySubClass: MyClass {} let myClass = MySubClass() print(myClass.isKind(of: MyClass.self)) // → true
isMemberOfClass
isMemberOfClassはisKindOfClassと違って、サブクラスとの判定はfalseになります。
class MyClass: NSObject {} class MySubClass: MyClass {} print(MyClass().isKind(of: MyClass.self)) // → true print(MySubClass().isKind(of: MyClass.self)) // → false
is
isはisKindOfClass同様、サブクラスとの判定もtrueになります。
isKindOfClassと違い、NSObjectProtocolに準拠していないクラスでも使えます。
class MyClass {} class MySubClass: MyClass {} print(MyClass() is MyClass) // → true print(MySubClass() is MyClass) // → true
isMemberOfClass相当の判定方法
NSObjectProtocolに準拠してないクラスでisMemberOfClass同様の判定をしたい場合は、下の方法が使えそうです。
String(describing: type(of: myClass))と"(MyClass.self)"はクラス名を返すので、サブクラスとの比較がfalseになります。
class MyClass {} class MySubClass: MyClass {} let myClass = MyClass() let mySubClass = MySubClass() print(String(describing: type(of: myClass)) == "\(MyClass.self)") print(String(describing: type(of: mySubClass)) == "\(MyClass.self)")
文字列での判定なので、下のように別フレームワークと同じクラス名を使ってる場合は注意が必要です。
class UIView {} print(UIView() is UIKit.UIView) // → false print(String(describing: type(of: UIView())) == "\(UIKit.UIView.self)") → true