2
import Cocoa

class Brain{
    var internalProgram = [AnyObject]()
    var program:AnyObject{
        get{
            return (internalProgram as AnyObject)
        }
    }
}

var savedProgram: AnyObject?
let brain = Brain()
func save(){
    savedProgram = brain.program
}

在没有 Xcode 给出警告或错误的情况下如何internalProgram:[AnyObject]返回?AnyObject我知道它program的类型已经设置好了,AnyObject但我的意思是这怎么能工作而不应该是这样[AnyObject]?那么为什么没有任何警告或错误问题呢?

4

2 回答 2

5

那么为什么没有任何警告或错误问题呢?

如果你没有说as AnyObject

class Brain {
    var internalProgram = [AnyObject]()
    var program: AnyObject {
        get {
            // compiler error:
            // Return expression of type '[AnyObject]' does not conform to 'AnyObject'
            return internalProgram
        }
    }
}

编译器告诉我们这[AnyObject]不符合AnyObject- 这是完全正确的。SwiftArray是 a struct,而不是 a class,因此不能直接键入为 a AnyObject

然而,你接着说as AnyObject。通过这样做,您将SwiftArray接到NSArray(当 Foundation 被导入时)——这一个class. 因此,它可以键入为AnyObject. 您可以在此处查看可以桥接到的 Foundation 类型的完整列表。

此外值得注意的是,在 Swift 3 中,由于引入了 opaque类型,一切都可以桥接AnyObject_SwiftValue,它可以将任意 Swift 值包装在 Obj-C 兼容的盒子中(包括Array不导入 Foundation 时)。

因为现在任何东西都可以是AnyObject,所以它几乎和 . 一样弱Any。最重要的是,它还允许您在其上调用任何已知@objc方法,完全无视类型安全性,并且几乎肯定会给您带来_SwiftValue拳击问题。由于这些原因,您应该尽可能避免使用AnyObject几乎总有一种更强大的类型可供您使用。

于 2017-03-22T14:39:17.620 回答
2

根据Apple 的文档,AnyObject可以在以下情况下使用:

  • 您需要无类型对象的灵活性
  • 您使用返回无类型结果的桥接 Objective-C 方法和属性

它基本上可以用作任何类的任何实例的类型,不管它是什么。因此,,[AnyObject]转换为NSArray, 仍然是一个AnyObject可以容纳的对象,因为它的类型无关紧要,因为AnyObject可以容纳任何类类型,例如NSArray.


解释:

[AnyObject]是一个对象数组,所以它是一个值类型。但是,当Foundation被导入时,数组可以自动转换为 Objective-C 桥接类型NSArray,即AnyObject

于 2017-03-22T14:16:59.260 回答