Any与AnyObject,AnyClass

2019-01-31

Any

在Swift中Any是什么?在Swift中是这样定义的:public typealias Any = protocol<> 。是一个空协议集合的别名,它表示没有实现任何协议,因此可以是任何类型,包括函数,枚举,结构体,保持类型的原生状态(不会隐式转换),可以存储swift的类型或者Object-C类型。所有类型都隐式遵守了这个协议。官方文档是这样解释的/// The protocol to which all types implicitly conform.

看看具体内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class MediaItem {
var name: String
init(name: String) {
self.name = name
}
}
class Movie: MediaItem {
var director: String
init(name: String, director: String) {
self.director = director
super.init(name: name)
}
}
var things = [Any]()
things.append(9)
things.append(9.0)
things.append("hello")
typealias closureType2 = @convention(block)(String) -> String
let closureGreet2: closureType = {
(name: String) -> String in
return "Hello, \(name)"
}
things.append(closureGreet2)
things.append({(name: String) -> String in "Hello, \(name)"})
things.append(Movie(name: "Ghostbusters", director: "Ivan Reitman"))
let optionalNumber: Int? = 3
things.append(optionalNumber as Any)
let OCArray: NSArray = ["a","b"];
things.append(OCArray)
let number = 4 as NSNumber
things.append(number)
print(things)
for object in things {
print(type(of: object))
}

看看显示结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[9, 9.0, "hello", (Function), (Function), __lldb_expr_30.Movie, Optional(3), <__NSArrayI 0x600003275b40>(
a,
b
)
, 4]
Int
Double
String
@convention(block) (String) -> String
(String) -> String
Movie
Optional<Int>
__NSArrayI
__NSCFNumber

类型保持了原生状态,包括OC中的数据类型,注意@convertion(block)类型,待会对比。

AnyObject

苹果官方文档是这样定义的:@objc public protocol AnyObject { } ,可以表示任何class类型的实例,来替代OC中的id类型,也就是swift转OC的桥梁。所有的类都隐式遵循了这个协议,官方文档the protocol to which all classes implicitly conform.

我们来看看使用AnyObject会发生什么情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class MediaItem {
var name: String
init(name: String) {
self.name = name
}
}
class Movie: MediaItem {
var director: String
init(name: String, director: String) {
self.director = director
super.init(name: name)
}
}
var objects: [AnyObject] = [AnyObject]()
// 元祖类型不是一个类的实例
objects.append((3.0,5.0) as AnyObject)
//字面量不是 一个类的实例
objects.append(0 as AnyObject)
objects.append("hello" as AnyObject)
struct Person {
var name: String
init(name: String) {
self.name = name
}
}
let jack = Person(name: "jack")
objects.append(jack as AnyObject)
let alpha = ["a","b"]
objects.append(alpha as AnyObject)
objects.append(Movie(name: "Ghostbusters", director: "Ivan Reitman"))
// 函数 不是一个实例
typealias closureType = @convention(block)(String) -> String
let closureGreet: closureType = {
(name: String) -> String in
return "Hello, \(name)"
}

objects.append(closureGreet as AnyObject)
objects.append({(name: String) -> String in "Hello, \(name)"} as AnyObject )
let optionalNum: Int? = 3
objects.append(optionalNum as AnyObject)
let ocArray: NSArray = ["c","d"]//OC 中 的 NSArray类型
objects.append(ocArray)

for object in objects {
if let obj = object as? (String)->String {
print(obj("World!\(obj)"))
}
print(type(of: object))
}
print(objects)

输出结果显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
_SwiftValue
__NSCFNumber
NSTaggedPointerString
_SwiftValue
_SwiftDeferredNSArray
Movie
__NSMallocBlock__
Hello, World!(Function)
_SwiftValue
__NSCFNumber
__NSArrayI
[(3.0, 5.0), 0, hello, __lldb_expr_36.Person(name: "jack"), <Swift._SwiftDeferredNSArray 0x60000398e7a0>(
a,
b
)
, __lldb_expr_36.Movie, <__NSMallocBlock__: 0x60000378dda0>, (Function), 3, <__NSArrayI 0x600003984f60>(
c,
d
)
]

可以看出AnyObject隐式转换了类型,对于Tuplestruct类型,OC并不存在或者定义不一样,所以保持swift的值类型,对于使用了@conversion(block)修饰一个闭包,被转换成了__NSMallocBlock__,真正转换成OC中的block块,如果把@conversion(block)去掉,会转换成一个(Function),仅仅被当成普通函数。可以看使用Any的时候对比下。

AnyClass

AnyClass 表示任意类的元类型,苹果官方文档:public typealias AnyClass = AnyObject.Type , 解释道:/// The protocol to which all class types implicitly conform.任意类的类型都隐式遵守这个协议.其中 .Type就是获得元类型的。注意如果某个变量或者常量的类型是AnyClass,你需要显示的转换成具体类型,然后再调用init()方法实例对象。参考:swift根据类型(AnyClass)创建对象

相关文章推荐

Any和AnyObject

AnyClass