Swift元型(类型,自我)

时间:2016-01-27 10:46:45

标签: swift

我想了解:“self, dynamicType, Type”。我有这段代码:

class SomeClass {}

let cls : SomeClass.Type = SomeClass.self
let cls2 : SomeClass = SomeClass()

clscls2是一回事吗?

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

2 个答案:

答案 0 :(得分:29)

不,clscls2是不同的事情。理解差异的最简单方法是扩展您的示例:

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.")
    }
}

现在让我们带你的cls

let cls : SomeClass.Type = SomeClass.self
cls.doIt()

这将打印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

我们带你的cls2。唯一可见的方法是doItOnlyIfInstanceOfThisType,因为它是一种实例方法(此类型)。

let cls2 : SomeClass = SomeClass()
cls2.doItOnlyIfInstanceOfThisType()

因此,它们之间的区别在于cls是一种类型,cls2是此类型的实例。

关于为什么SomeClass.self和SomeClass()的更多知识?

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

SomeClass()调用init()的{​​{1}}方法,SomeClass是一个创建SomeClass实例的构造函数。

PRO提示

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

let myFunc :()->() = cls.doItOnlyIfInstanceOfThisType(cls2)
myFunc()

答案 1 :(得分:5)

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

您可以使用后缀自我表达式将类型作为值进行访问。例如,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"

someInstance的编译时类型为SomeBaseClasssomeInstance的运行时类型为SomeSubClass

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

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

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

Swift 3.0:

不推荐使用

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

type(of: someInstance).printClassName()