Swift元型(类型,自我)

sam*_*mir 11 swift

我想了解:" self, dynamicType, Type".我有这个代码:

class SomeClass {}

let cls : SomeClass.Type = SomeClass.self
let cls2 : SomeClass = SomeClass()
Run Code Online (Sandbox Code Playgroud)

是cls和cls2同样的事情?

有人可以提供一些关于差异的细节吗?谢谢

Rad*_*iwa 31

不,cls而且cls2是不同的事情.理解差异的最简单方法是扩展您的示例,如下所示:

class SomeClass {
    class func doIt() {
        print("I'm a class method. I belong to my type.")
    }

    func doItOnlyIfInstanceOfThisType() {
        print("I'm a instance method. I belong to my type instance.")
    }
}
Run Code Online (Sandbox Code Playgroud)

现在让我们来看看你的cls:

let cls : SomeClass.Type = SomeClass.self
cls.doIt()
Run Code Online (Sandbox Code Playgroud)

那将打印出来I'm a class method. I belong to my type..但你不能调用这个:

cls.doItOnlyIfInstanceOfThisType() // causes a compilation error, PRO TIP: actually you can use this method as a func property, but I'll add the explanation for this later
Run Code Online (Sandbox Code Playgroud)

我们带你的吧cls2.唯一可见的方法是doItOnlyIfInstanceOfThisType因为它是一个实例方法(这种类型).

let cls2 : SomeClass = SomeClass()
cls2.doItOnlyIfInstanceOfThisType()
Run Code Online (Sandbox Code Playgroud)

所以它们之间的区别在于它cls是一种类型,cls2是这种类型的一个实例.

关于SomeClass.self和SomeClass()的原因有点多了解?

类的类型也存在于内存中(例如它有自己的方法),作为表示Type的单例(不是这种类型的实例 - 这是不同的东西).如果你调用self类似这样的类型,SomeClass.self你将得到一个代表SomeClassType 的单例实例.

SomeClass()调用创建实例的构造函数的init()方法.SomeClassSomeClass

专家提示

您可以操作Type实例函数(如ObjC中的闭包/块).这是一个生成的类方法.但是您必须将此方法类型的实例作为参数传递,如下所示:

let myFunc :()->() = cls.doItOnlyIfInstanceOfThisType(cls2)
myFunc()
Run Code Online (Sandbox Code Playgroud)


a_t*_*tuo 6

元类型类型是指任何类型的类型,包括类类型,结构类型,枚举类型和协议类型.

您可以使用后缀自表达式将类型作为值进行访问.例如,SomeClass.self返回SomeClass自身,而不是实例SomeClass.并SomeProtocol.self返回SomeProtocol自身,而不是SomeProtocol在运行时符合的类型的实例.您可以使用具有dynamicType类型实例的表达式来访问该实例的动态,运行时类型作为值,如以下示例所示:

class SomeBaseClass {
    class func printClassName() {
        print("SomeBaseClass")
    }
}
class SomeSubClass: SomeBaseClass {
    override class func printClassName() {
        print("SomeSubClass")
    }
}
let someInstance: SomeBaseClass = SomeSubClass()
someInstance.dynamicType.printClassName()
// prints "SomeSubClass"
Run Code Online (Sandbox Code Playgroud)

编译时类型someInstance是SomeBaseClass,运行时类型someInstance是SomeSubClass

您可以使用标识运算符(===和!==)来测试实例的运行时类型是否与其编译时类型相同.

if someInstance.dynamicType === SomeBaseClass.self {
    print("The dynamic type of someInstance is SomeBaseCass")
} else {
    print("The dynamic type of someInstance isn't SomeBaseClass")
}
Run Code Online (Sandbox Code Playgroud)

更多细节 - > Swift编程语言:类型

Swift 3.0:

.dynamicType不推荐使用,您应该使用它type(of:)来获取其元类型:

type(of: someInstance).printClassName()
Run Code Online (Sandbox Code Playgroud)