Swift - Any 和 AnyObject
Any
和 AnyObject
是Swift
中两个妥协
的产物,也是很让人迷惑的概念。在Swift官方变成指南中指出:
AnyObject
可以代表任何Class
类型的实例Any
可以表示任意
类型,甚至包括方法(func)
类型
AnyObject
先来说说AnyObject
吧。写过Objective-C
的读者可能会知道在Objective-C中有一个叫做id
的神奇的东西。编译器不会
对申明为id
的变量进行类型检查
,它可以表示任意类
的实例
。在 Cocoa
框架中很多地方都使用了id
来进行像参数传递
和方法返回
这样的工作,这是Objective-C动态特性
的一种表现。现在的Swift
最主要的用途依然是使用Cocoa框架
进行App开发
,因此为了与Cocoa架构协作
,使用了一个类似的
,可以代表任意class类型
的AnyObject
来替代原来id
的概念。
但两者
其实是有本质区别
的。在Swift
中编译器不仅不会
对AnyObject实例
的方法调用做出检查
,甚至对于AnyObject
的所有方法调用
都会返回Optional
的结果。这虽然
是符合Objective-C
中的理念
的,但是在Swift环境
下使用起来就非常麻烦
,也很危险
。应该选择的做法是在使用时先确定
AnyObject真正
的类型
并进行转换以后
再进行调用
。
假设原来的某个API返回
的是一个id
,那么在Swift中
就被映射为AnyObject?
(因为id
是可以指向nil
的,所以在这里我们需要一个Optional
的版本),虽然我们知道调用应该是没问题的,但是我们依然最好这样写:
func someMethod() -> AnyObject? {let result: AnyObject = 1 as NSNumber// ...// 返回一个AnyObject?,等价于在 Objective-C 中返回一个 idreturn result
}
let anyObject: AnyObject? = someMethod()
if let someInt = anyObject as? Int {// ...// 这里我们拿到了具体 Int 的实例let _ = someInt + 1
}
如果我们注意到AnyObject
的定义,可以发现它其实就是一个协议接口
/// The flexible behavior of the `AnyObject` protocol is similar to
/// Objective-C's `id` type. For this reason, imported Objective-C types
/// frequently use `AnyObject` as the type for properties, method parameters,
/// and return values.
public typealias AnyObject
特别之处在于,所有的class
都隐式
地实现了AnyClass
接口,而AnyClass
为AnyObject.Type
,这也是AnyObject只
适用于class类型
的原因。
public typealias AnyClass = AnyObject.Type
Any
而在Swift
中所有的基本类型
,包括Array
和Dictionary
这些传统意义上是class
的东西,全部都是struct类型
,并不能
由AnyObject
来表示,于是Apple
提出了一个更为特殊
的Any
,除了class以外,它还可以表示包括struct
和enum
在内的所有类型
。
为了深入理解,举个很有意思的例子。为了实验Any
和AnyObject
的特性,我们写下如下代码:
import UIKitlet swiftInt: Int = 1
let swiftString: String = "miao"var array: [AnyObject] = []
array.append(swiftInt)
array.append(swiftString)
我们这里声明了一个Int
和一个String
,你会发现这段代码编译报错
。
Argument type 'Int' expected to be an instance of a class or class-constrained type
即使用的参数应为类
或者类的实例
对象,如果我们将上方的代码中的AnyObject
换成Any
,就可以编译成功。
let swiftInt: Int = 1
let swiftString: String = "miao"var array: [Any] = []
array.append(swiftInt)
array.append(swiftString)
如果将Int
替换成NSInteger
,或者String
替换成NSString
,编译
依然成功
let swiftInt: NSInteger = 1
let swiftString: NSString = "miao"var array: [Any] = []
array.append(swiftInt)
array.append(swiftString)
总结
值得一提的是,只使用
Swift类型而不转为
Cocoa类型,对性能提升
是有所帮助
的,所以我们应该尽可能
的使用原生类型
。
其实说真的,使用Any
和AnyObject
并不是
什么令人愉悦的事情,正如开头所说,这都是妥协的产物
。如果在我们自己的代码里经常使用
这两者的话,往往意味着代码
可能在结构
和设计
上存在问题
,应该及时重新审视
。简单来说,我们最好避免使用
甚至依赖
两者,而去尝试明确的指出确定
的类型
。
Swift - Any 和 AnyObject相关推荐
- Swift学习: 从Objective-C到Swift
作者:@方秋枋(GitHub) 这篇文章是自己学习Swift的笔记与深化.希望这篇文章能够帮助已经有Objective-C经验的开发者更快地学习Swift.同时也品味到Swift的精妙之处. 结论放在 ...
- Swift与Objective-C交互
在同一个工程中是可以同时使用Swift和OC的,但不可以同时出现在同一个文件中. OC调用Swift相关信息的方法 在***.m文件中导入工程名-Swift.h即可. 如工程名为ABC,则在需要使用S ...
- 使用swift语言进行IOS应用开发
在Swift中能够直接使用Objective-C语言提供的api (包括系统框架与自己的定制代码),也能够在Objective-C中使用Swift提供的类和api ,还能够在一个工程中同时混合使用Sw ...
- 如何提高 Xcode 的编译速度
本文总结自 WWDC 2018 building faster in xcode 该 Session 通过一系列的实践来实现 Xcode 的快速编译,共阐述了六个大方面,分别是: 将编译过程并行化 通 ...
- Swift 类型的检査与转换(is,as,AnyObject,Any)
is和as 类型转换 可以判断实例的类型,也可以将实例看做是其父类或者子类的实例. 类型转换在 Swift 中使用 is 和 as 操作符实现.这两个操作符提供了一种简单达意的方式去检查值的类型或者转 ...
- swift文件服务器,Swift3一行代码将各种类型文件上传到服务器
由于之前一直在忙项目,很久没有写过一篇像样的文章了,现在手上的项目基本是完成了,正好工作时间偷个懒写两篇文章. 将相机或相册图片上传到服务器 先看看最常见的图片上传,也可以选择跳过,后面有直接的封装方 ...
- iOS 视频捕获系列Swift之AVFoundation(一)
iOS 视频捕获系列之AVFoundation(一) AVCaptureMovieFileOutput系列 在iOS开发过程中,或多或少的都涉及视频的操作. 尤其在去年直播行业的带动下,移动端对视频的 ...
- Swift - 使用Alamofire通过HTTPS进行网络请求,及证书的使用
(本文代码已升级至Swift3) 我原来写过一篇文章介绍如何使用证书通过SSL/TLS方式进行网络请求(Swift - 使用URLSession通过HTTPS进行网络请求,及证书的使用),当时用的是 ...
- swift实现提示框第三方库:MBProgressHUD
GitHud的下载地址是:https://github.com/jdg/MBProgressHUD/ 下载完成后,将MBProgressHUD.h和MBProgressHUD.m拖入已经新建好的Swi ...
最新文章
- 模型在gpu上反而速度变慢了_Tensorflow1.13.1+CUDA10.0+CuDNN7.4在GPU上训练模型
- 关于 IPv6 大规模部署,给我们带来了什么~
- Visual Studio 2017 15.5.0 正式发布 正式版下载
- 【转】android多分辨率适配
- 风靡全球的15则数学动图:让你秒懂数学概念,看后觉得相见恨晚啊
- linux下qt环境的运行,在Linux下使用QT环境来安装和运行WebKit
- Android应用程序管理系列(四)—— packagemanager flags 与 packageInfo
- 理解SQL SERVER中的分区表(转)
- 使用rmats进行可变剪切的分析
- 【scratch案例教学】scratch中秋佳节 scratch创意编程 少儿编程 边玩边学 小朋友这样贺中秋
- PHP学习笔记——图形图像
- eclipse快捷键壁纸
- Jsp文件修改后不生效怎么办?
- html网页中如何给文字加入下划线
- 武汉新时标文化传媒有限公司抖音小店公告标题怎么写?
- 【用Python学习Caffe】7. 网络结构的修剪
- 三维建模之太空战舰——我们的征途是星辰大海!
- Ubuntu18+ 使用redshift调色温 夜间闪烁
- ctfshow 月饼杯(第二届) 部分WriteUp
- GLES2.0中文API-glFramebufferTexture2D
热门文章
- 南京大学计算机科学与技术就,南京大学计算机科学与技术怎么样
- 盘它!H3C X3至尊版无线路由器评测
- 智能座舱HIL测试系统
- element el-input 只能输入正整数完美解决不闪动
- CF1550C Manhattan Subarrays(思维)
- 【学习】深度学习代码各个步骤都是为了啥(三)
- ThinkPHP_防止表单重复提交
- macbook蓝牙pan未连接_LOFREE洛斐Dot圆点蓝牙机械键盘 洛斐MAUS薯片蓝牙鼠标使用评测...
- php 发邮件附件,php发送电子邮件附件
- 指纹模块原理_光学指纹模块原理