美文网首页swift学习专题
Swift中AnyObject和Any的介绍与区别详解

Swift中AnyObject和Any的介绍与区别详解

作者: 6ffd6634d577 | 来源:发表于2019-04-23 14:38 被阅读0次

    诞生

    swift 作为新起步的语言,必然抛不掉一些历史遗留包袱。用过 Objective-C 的同学肯定知道有一种叫做 id 的类型。他可以表示任意类的实例,编译器不会对其类型声明的变量进行检查。在用 swift 做 app 开发时,为了能适配 Cocoa 架构,AnyObject 就诞生了。它可以代表任意 class 类型(用来替代OC中的 id)。

    区别

    在 Swift 中编译器会对 AnyObject 实例的方法调用做检查,还会返回一个 Optional 的结果。

    原理

    public typealias AnyObject
    // The protocol to which all class types implicitly conform.
    

    由定义就可以看出它就是一个接口,所有的 class 都隐式地实现了这个借口。所以 AnyObject 只适用于 class 类型。但是 swift 中的基本类型都是 struct 类型,并不能用 AnyObject 来表示。所以官方又提出了一个更特殊的 Any 类型,它除了 class 以外还可以表示其他类型,可以说是任意类型(包括 struct,enum,func等)。

      let swiftArr = ["a", "b", "c"]
      let swiftStr = "hello world"  
      var array = [AnyObject]()
      array.append(swiftArr)
      array.append(swiftStr)
    

    这种写法是会报错的,String 不符合预期类型 AnyObject,并且系统提示了我们怎么修改:

    Argument type '[String]' does not conform to expected type 'AnyObject'
    Insert ' as AnyObject'
    
    image.png

    当然我们还有另外的方式解决此问题,用 Any。

      let swiftArr = ["a", "b", "c"]
      let swiftStr = "hello world"  
      var array = [Any]()
      array.append(swiftArr)
      array.append(swiftStr)
    

    可以看到结果全部是 swift 中的原生类型:

    image.png

    注意

    • 只是用 swift 类型而不转为 Cocoa 类型是会提升性能的,所以我们最好还是使用原生类型。
    • 在 OC 和 swift 混编的工程中使用 AnyObject 和 Any 是在所难免的,但我们要尽量避免使用这两者,swift 中最好明确地指出确定的类型。
    • 如果我们的代码经常用到这两者,意味着代码可能在结构和设计上存在问题。

    下面来举例说明:

    1.Any -- 比如我们经常使用的参数parameters

    parameters = ["appId":"123456", "timestamp":203428394820,
    "version":"1.0", "appAuthToken":"7D8SF7D8VS8987D67687", 
    "bizContent":["pageStart":1, "pageSize": "10","isTrue":true]] as [String : Any]
    

    这里面包括了String,Int,Bool,Dictionnary四种类型的参数,最后使用as [String : Any] ,就是说,parameters的key是String类型,但是value值可以是任何类型。

    2.AnyObject -- 在做网络请求的时候

    typealias Complicate = (AnyObject) ->Void
    //请求回调
    var complicate : Complicate?
    func request(type:RequestType, URLString:String, parameters:[String : AnyObject], complicate:@escaping Complicate) -> Void {
    CK().maskShow()
    switch type {
    case .requestTypeGet:
    Alamofire.request(URLString, method: .get, parameters: parameters, encoding: JSONEncoding.default, headers: nil)
    .validate()
    .responseJSON { response in
    CK().dismissMask()
    switch response.result{
    case .success:
    if let value = response.result.value{
    //把得到的JSON数据转为字典
    complicate(value as AnyObject)
    }
    case .failure: ()
    DMCAlertCenter.default().postAlert(withMessage: "网络请求失败")
    return
    }
    }
    

    可以看到,在返回的json进行回调的时候,由于value是JSON类型的实例,complicate(value as AnyObject), 就是将value作为AnyObject传值出去。

    3.AnyClass
    属于AnyObject.Type的别名:typealias AnyClass = AnyObject .Type表示任意类的元类型,任意类的类型都隐式遵守这个协议.

    4. AnyHashable
    Swift的Any类型可以保存任何类型,但是Dictionary和Set需要的的类型是要求遵守Hashable协议的类型,所以Any表示的太广泛。 从Swift 3开始,Swift标准库提供了一个新的类型AnyHashable。 与Any类似,它充当所有Hashable类型的父类,因此String、Int和其他hashable类型的值都可以隐式地用作AnyHashable值,AnyHashable类型的值可以使用is、as !动态检查或者使用as?动态转换运算符。

    相关文章

      网友评论

        本文标题:Swift中AnyObject和Any的介绍与区别详解

        本文链接:https://www.haomeiwen.com/subject/ciqmwttx.html