Swift2:理解AnyObject和Self

Swift 2: understanding AnyObject and Self

我找不到对我的问题的任何好的解释,所以我想直接问你。首先,我想在 .

中完善我的代码

我的问题是协议 AnyObjectSelf 类型。我没有在我的代码中实现 AnyObject 因为它标有 @objc 并且我不希望我的代码中涉及任何 Objective-C 东西(不要因此而评判我)。我也找不到关于 Self 类型的任何解释。它按预期工作,但 Xcode 不会将 Self 替换为调用静态函数的类型。

这里是一些例子:

extension Int : Instance {}

Int.singleton { (customInstanceName) -> Self in 0 } // Self shall be replaced with Int

如您所见,Xcode 生成一个 Self 而不是一个 Int。我有机会解决这个问题吗?我对 Self 执行 return dynamicType 并且我的实现很好,就像我上面的 post 一样吗?我真的很感激关于 Self 类型的任何好的解释。

正如您在我的代码中看到的那样。我正在使用自定义协议来检查我的实例是否为 class。是否有任何其他闪亮的实现来检查我的实例,如果它们是 classes 或结构类型,或者如果我想摆脱我的 ClassInstance 协议,我是否被迫使用 AnyObject

感谢您的宝贵时间。

更新:

protocol Test {}

class A : Test {}

struct B : Test {}

let aClass : Test = A()
let aStruct : Test = B()

if let someClass = aClass as? AnyObject {
    print(someClass) // only this will print
}

if let someStruct = aStruct as? AnyObject {
    print(someStruct)
}

这会起作用,但 AnyObject 仍被标记为 @objc 协议。

Self 类型只能用于隐式 typealias 符合它的类型的协议:

protocol Testable {
    func test() -> Self
}

如果您想遵守此协议,则必须将 Self 替换为类型名称。例如:

struct Product: Testable {
    func test() -> Product {
        return Product()
    }
}

重要编辑:

正如 DevAndArtist 在评论中指出的那样,在 Swift 1.2(没有自动桥接到 Objective C)中有一个有效的 class 检查,但没有 Swift 2(Xcode 7 beta 3;可能是一个错误):

if instance.dynamicType is AnyClass {
    // instance is a class
} else {
    // instance is not a class
}

您可以在下面查看 Swift 2 的解决方法(主要)。

结束编辑

关于 classes,如果您想保持简单,您应该使用 AnyObject,但您也可以使用反射,这会更加费力。

下面可以看到一些字符串插值的反映结果(只有前几个字符):

"\(reflect(classType))"                  // Swift._ClassMirror
"\(reflect(0))"                          // Swift._LeafMirror
"\(reflect(enumType))"                   // Swift._EnumMirror
"\(reflect(structure))"                  // Swift._StructMirror
"\(reflect([0, 4]))"                     // Swift._ArrayTypeMirror
"\(reflect(NSDate()))"                   // Foundation._NSDateMirror
"\(reflect(NSURLRelationship.Contains))" // Swift._EnumMirror
"\(reflect(Int?(2)))"                    // Swift._OptionalMirror

如您所见,如果未在 Swift 标准库中定义枚举,则枚举是一致的(不幸的是也是可选的...)。所以你也可以区分结构和枚举:

public enum Type {
    case Enum, Class, Struct
}

public func getType<T>(anything: T) -> Type {
    if anything is AnyObject {
        return .Class
    }
    if "\(reflect(anything))".hasPrefix("Swift._EnumMirror") {
        return .Enum
    }
    return .Struct
}

因此,为了获得更好的结果,您必须付出一些努力来区分所有不同的情况。

但是仅区分引用类型和值类型(又名 classes 和 structs/enums)的最简单方法仍然是(不幸的是只适用于自己声明的结构而不适用于内置类型,因为它们可以桥接到 Objective C;我正在努力...):

if instance is AnyObject {}

// or: if instance is of type Any
if let classInstance = instance as? AnyObject {}