swift 2 : understanding AnyObject and Self

标签 swift protocols

我找不到任何好的解释来回答我的问题,所以我想直接问你。首先,我想在这个 post 中完善我的代码。 .

我的问题是协议(protocol) 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 类型的好的解释。

正如您在我的代码中所看到的。我正在使用自定义协议(protocol)来检查我的实例是否是一个类。是否有任何其他 Shiny 的实现来检查我的实例是否是类或结构类型,或者如果我想摆脱我的 ClassInstance 协议(protocol),我是否被迫使用 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 协议(protocol)。

最佳答案

Self 类型只能在协议(protocol)中使用,该协议(protocol)是符合它的类型的隐式 typealias:

protocol Testable {
    func test() -> Self
}

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

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

重要编辑:

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

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;我'我正在努力...):

if instance is AnyObject {}

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

关于 swift 2 : understanding AnyObject and Self,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31298059/

相关文章:

ios - SWIFT:创建具有不同原型(prototype)样式的 tableView

xcode - 更新swift后出现错误?

ios - 导入协议(protocol)时没有类型或协议(protocol)错误

swift - 为什么排序(by :) unavailable in extensions to MutableCollection?

ios - 如何在具有相同协议(protocol)变量的 Swift 中使用多个协议(protocol)?

ios - 是否可以格式化 dateComponent 以显示为 hh :mm:ss?

ios - 日历应用程序想要快速与 ios 日历同步

ios - AWS Cognito Swift SDK 如何检查用户是否已确认?

ios - swift 3 从父 ViewController 调用函数

google-chrome - 从网站启动 Chrome 打包的 Web 应用程序