Where is it used?
If you write / create a function that takes a type, for example, UIView.Type , and not an instance, for example, UIView() then you should write T.Type as the parameter type. What it expects as a parameter can be: String.self , CustomTableView.self , someOtherClass.self .
But why does a function need a type?
Usually a function that requires a type is a function that creates objects for you. I can recall two good examples:
- register function from table
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "CustomTableViewCell")
Please note that you passed CustomTableViewCell.self . If later you try to remove a CustomTableViewCell type from the tableView but do not register a CustomTableViewCell type, then it will fail because tableView did not remove from the queue / did not create any viewview elements of the CustomTableViewCell type cell.
- decoding function from JSONDecoder . Link example
struct GroceryProduct: Codable { var name: String var points: Int var description: String? } let json = """ { "name": "Durian", "points": 600, "description": "A fruit with a distinctive scent." } """.data(using: .utf8)! let decoder = JSONDecoder() let product = try decoder.decode(GroceryProduct.self, from: json) print(product.name)
Please note try decoder.decode(GroceryProduct.self, from: json) . Since you passed GroceryProduct.self he knows that he needs to instantiate an object of type GroceryProduct . If he canβt, it gives an error
- For an alternative workaround where types are needed, see the following question: Swift cannot determine a universal type when a universal type is passed through a parameter . The accepted answer offers an interesting alternative.
More on the insides and how it works:
.Type of
The metatype of a class, structure, or enumeration type is the name of that type, followed by .Type. The metatype of the protocol type, not the specific type that matches the protocol at runtime, is the name of that protocol, followed by .Protocol. For example, the metatype of the SomeClass class SomeClass is SomeClass.Type and the SomeProtocol protocol SomeProtocol is SomeProtocol.Protocol .
From Apple: Meta Type
AnyClass is under the hood
typealias AnyClass = AnyObject.Type
Mostly AnyClass , where you see AnyClass , Any.Type , AnyObject.Type , because it needs a type. The very common place we see is when we want to register a class for our tableView using register func.
func register(_ cellClass: Swift.AnyClass?, forCellReuseIdentifier identifier: String)
If you are not sure what Swift means. do then then see comments from here
The above can also be written as follows:
func register(_ cellClass: AnyObject.Type, forCellReuseIdentifier identifier: String)
.self
You can use postfix self-expression to access the type as a value. For example, SomeClass.self returns SomeClass itself, not an instance of SomeClass. And SomeProtocol.self returns SomeProtocol itself, not an instance of the type that matches SomeProtocol at run time. You can use an expression of type (of :) with an instance of a type to access dynamic instance types as a value, as shown in the following example:
From Apple: Meta Type
Playground Code:
Simple example
struct Something { var x = 5 } let a = Something() type(of:a) == Something.self
Hard example
class BaseClass { class func printClassName() { print("BaseClass") } } class SubClass: BaseClass { override class func printClassName() { print("SubClass") } } let someInstance: BaseClass = SubClass() type(of: someInstance) == SubClass.self
I highly recommend reading Apple's type documentation . See also here