Swift 2:理解AnyObject和Self

时间:2015-07-08 16:09:46

标签: swift protocols

我无法对我的问题找到任何好的解释,所以我想直接问你。首先,我想在此post中优化我的代码。

我的问题是协议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确实返回了dynamicType,我的实现很好,因为它在我上面的帖子中?我真的很感激有关Self类型的任何好解释。

正如您在我的代码中看到的那样。我正在使用自定义协议来检查我的实例是否是一个类。如果它们是类或结构类型,是否有任何其他闪亮的实现来检查我的实例,或者如果我想摆脱我的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协议。

1 个答案:

答案 0 :(得分:1)

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

protocol Testable {
    func test() -> Self
}

如果要符合此协议,则必须将Self替换为类型名称。例如:

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

重要编辑:

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

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

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

结束修改

关于课程,你应该使用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
}

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

但是,仅仅区分引用类型和值类型(也就是类和结构/枚举)的最简单方法仍然是(遗憾的是只能用于自己声明的结构而不是内置类型,因为它们可以桥接到Objective C; I&# 39;正在努力......):

if instance is AnyObject {}

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