Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a AnyClass variable is an extension or implementation of a class

Tags:

swift

Having a variable of type AnyClass, is it possible to know if that type is an extension or implementation of another type?

For example:

var aClass: AnyClass = UIButton.self

// assuming a fictional operator "isOfType"
// Both UIButton and UILabel are subclasses of UIView
aClass isOfType UIButton // true
aClass isOfType UIView   // true
aClass isOfType UILabel  // false

One possible way to do this is creating an instance, but creating such instance may not be always desirable:

var aClass: AnyClass = UIButton.self

let buttonClass = aClass as? UIButton.Type
var aButton: AnyObject = buttonClass!()
aButton is UIButton // true
aButton is UIView   // true
aButton is UILabel  // false

Are there other means to check if a AnyClass contains a type that extends another type?

like image 407
Maic López Sáenz Avatar asked Sep 05 '15 18:09

Maic López Sáenz


1 Answers

You can use isSubclassOfClass if the receiving class inherits from NSObject.

let c = UIButton.self
print(c.isSubclassOfClass(UIButton.self)) // true
print(c.isSubclassOfClass(UIView.self)) // true
print(c.isSubclassOfClass(UILabel.self)) // false

Update: Although isSubclassOfClass is defined in NSObject, it seems to be usable for Swift classes that don't explicitly derive from NSObject as well. The below works as expected in Xcode 7 beta 6.

class A {
}

class B: A {
}

class C {
}

let c: AnyClass = B.self
print(c.isSubclassOfClass(A.self)) // true
print(c.isSubclassOfClass(B.self)) // true
print(c.isSubclassOfClass(C.self)) // false

I believe that Swift classes that don't inherit from NSObject still share some of its methods for compatibility reasons. I couldn't find any official documentation on this, however, and Xcode won't even let me navigate to the declaration of isSubclassOfClass from the snippet above.

Update 2: An alternative that works regardless of whether the classes inherit from NSObject or not is to use is together with the Type property.

let c: AnyClass = UIButton.self        
print(c is UIButton.Type) // true
print(c is UIView.Type) // true
print(c is UILabel.Type) // false

let c: AnyClass = B.self
print(c is A.Type) // true
print(c is B.Type) // true
print(c is C.Type) // false
like image 109
hennes Avatar answered Oct 03 '22 08:10

hennes