Simon Hessner
Simon Hessner

Reputation: 1837

Swift 4: type(of:self).description() differs from String(describing: type(of:self))

I need to determine the dynamic type of my object in a method that is implemented in a super class. The super class is called BaseClient and DisplayClient inherits from it.

I only need the class name, not the package name. This is what I tried:

print("1", String(describing: type(of: self))) // DisplayClient
print("2", type(of: self))                     // DisplayClient
print("3", type(of: self).description())       // package.DisplayClient
print("4", "\(type(of: self))")                // DisplayClient

Why does

 type(of: self).description()

return package.DisplayClient while the others only return the class name? I wonder what is called internally when I use String(describing: type(of: self)). I would assume this does exactly what I do (call describing()).

Where can I find more info on how the strings get generated internally?

The docs say:

Use this initializer to convert an instance of any type to its preferred representation as a String instance. The initializer creates the string representation of instance in one of the following ways, depending on its protocol conformance:

But type(of: self) does not even have a description attribute. It only has a description() method. Is this some special case that is handled differently by the compiler?

Upvotes: 2

Views: 3727

Answers (1)

Martin R
Martin R

Reputation: 540005

If your class inherits from NSObject then type(of: self).description() invokes the NSObject.description() class method:

class func description() -> String

NSObject's implementation of this method simply prints the name of the class.

and it is not documented whether that includes the module name or not. If your class does not inherit from NSObject then there is no default description() method.

On the other hand,

print(String(describing: type(of: self))) // DisplayClient
print(type(of: self))                     // DisplayClient

both print the unqualified type name, and

print(String(reflecting: type(of: self))) // package.DisplayClient
debugPrint(type(of: self) )               // package.DisplayClient

both print the fully qualified type name, compare How to get a Swift type name as a string with its namespace (or framework name) and the Xcode 7 Release Notes:

Type names and enum cases now print and convert to String without qualification by default. debugPrint or String(reflecting:) can still be used to get fully qualified names.

Upvotes: 3

Related Questions