简体   繁体   English

Swift 2:了解AnyObject和Self

[英]Swift 2: understanding AnyObject and Self

I couldn't find any good explanation to my questions so I'd like to ask you directly. 我找不到任何对我的问题的很好的解释,所以我想直接问你。 First of all I'd like to refine my code in this post . 首先,我想在这篇文章中完善我的代码。

My problem is the protocol AnyObject and the Self type. 我的问题是协议AnyObjectSelf类型。 I didn't implement AnyObject into my code because it is marked with @objc and I don't want any Objective-C stuff involved in my code (don't judge me for that). 我没有在代码中实现AnyObject因为它用@objc标记,并且我不希望在代码中涉及任何Objective-C的东西(不要@objc )。 I also couldn't find any explanation about the Self type. 我也找不到有关Self类型的任何解释。 It just worked as expected, but Xcode does not replace Self with the type the static function is called at. 它只是按预期工作,但Xcode不会将Self替换为调用静态函数的类型。

Here is some example: 这是一些例子:

extension Int : Instance {}

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

As you can see Xcode produces a Self instead an Int. 如您所见,Xcode生成一个Self而不是一个Int。 Is there any chance I could fix this? 我有没有机会解决这个问题? Am I right that Self does return the dynamicType and my implementation is fine as it is in my post above? 我对,Self确实会返回dynamicType,并且我的实现与上面的帖子一样好吗? I would really appreciate any good explanation about the Self type. 我非常感谢您对Self类型的任何很好的解释。

As you have seen in my code. 如您在我的代码中所见。 I am using a custom protocol to check whether my instance is a class or not. 我正在使用自定义协议来检查我的实例是否是类。 Is there any other shiny implementation to check my instances if they are classes or structure types, or am I forced to use AnyObject if I want to get rid of my ClassInstance protocol? 是否还有其他闪亮的实现可以检查我的实例是否是类或结构类型,或者如果我想摆脱ClassInstance协议,是否必须使用AnyObject

Thank you for your time. 感谢您的时间。

UPDATE: 更新:

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

This will work, but AnyObject is still marked as an @objc protocol. 这将起作用,但是AnyObject仍被标记为@objc协议。

The Self type can be only used in protocols where it is a implicit typealias of the type which conforms to it: Self类型只能在符合以下类型的隐式类型typealias的协议中使用:

protocol Testable {
    func test() -> Self
}

If you want to conform to this protocol you than have to replace Self with the name of the type. 如果要遵守此协议,则必须用类型名称替换Self For instance: 例如:

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

Important Edit: 重要编辑:

As DevAndArtist pointed out in the comments there is a working class check in Swift 1.2 (without automatic bridging to Objective C) but not Swift 2 (Xcode 7 beta 3; probably a bug): 正如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
}

You can see workaround (mainly) for Swift 2 below. 您可以在下面看到Swift 2的解决方法(主要是)。

End Edit 结束编辑

With respect to classes you should use AnyObject if you want to keep it simple but you can also use reflection which would be much more effort. 对于类,如果要使其简单,则应使用AnyObject ,但也可以使用反射,这会花费更多的精力。

Below you can see some reflection results of string interpolations (only the first few characters): 在下面,您可以看到一些字符串插值的反射结果(仅前几个字符):

"\(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

As you can see enums are consistent if they are not defined in the Swift standard library (unfortunately also Optional...). 如您所见,如果未在Swift标准库中定义枚举,它们是一致的(不幸的是,也是可选的...)。 So you can distinguish also structs and enums: 因此,您还可以区分结构和枚举:

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
}

So for a better result you have to put some effort into it to differentiate between all the different cases. 因此,为了获得更好的结果,您必须付出一些努力来区分所有不同的情况。

But the easiest way to distinguish only between reference types and value types (aka classes and structs/enums) is still (unfortunately only works for own declared structs and not built in types because they can be bridged to Objective C; I'm working on it...): 但是,仅区分引用类型和值类型(又名类和结构/枚举)的最简单方法仍然是(不幸的是,仅适用于自己声明的结构而不是内置类型,因为它们可以桥接到目标C;我正在研究它...):

if instance is AnyObject {}

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM