Swift 中的集合 Array

集合 Array

在创建一个 Array 对象时,会默认为其分配指定的空间存储将要插入的值。随着插入的值的增加,如果空间不够,那么,数组会重新分配内存,并将原内存中的值拷贝到新内存中。
并且,新分配的内存的大小是旧内存大小的多倍。这个重新分配内存的操作对性能的消耗虽然会随着分配次数的增加而降低,但是如果能够估计将要保存的变量个数,
可以在创建数组时进行指定,从而避免触发内存的重新分配。

Array 中的内容一般都保存在一片连续的内存中,但是如果其所保存的变量是类,那么则另当别论。并且,Array 作为 struct ,将一个数组赋值给另一个数组变量,那么两个数组实际上均保存有自己的值。即,对各自所保存的变量进行修改,不会影响另一个数组中保存的值。不过,如果数组保存的是引用类型的变量,如类,那么对类实例属性的修改,会影响两个数组。但,如果是对某个数组中的类元素进行替换,或者添加、删除元素,那么,另一个数组仍然不会受到影响。

当然,数组在赋值时,其实并未进行拷贝,他们共享同一片内存中的内容,直到某个可变数组发生修改时,才会进行拷贝。

Array 可以使用 as 转换为 NSArray 从而使用 NSArray 类型的相关方法,但是这要求 Array 中保存的是类或者是遵循 @objc 协议的变量,或被 @objc 修饰的变量属性。
应当意识到 NSAarry 中是不能保存诸如结构体、枚举、可选类型等类型的。

var strA = ["1"]
strA.append("2")
let strNSA = (strA as NSArray).adding("3")
print(strA)
print(strNSA)

在来看 NSArray 和 NSMutableArray 的使用:

let array: NSArray = [1,"1"]
print(array)
    
let mutableArray: NSMutableArray = [1,"1"]
mutableArray.add("a")
print(mutableArray)

可以发现,Swift 中的 NSArray 支持直接存储基本数据类型,但实际上是 Swift 为你将其转换为了 NSObject 类型。

另外,我们还可以发现,这里使用 let 来声明 NSMutableArray 类型的变量,并不会限制其添加、删除和修改元素。

上述代码的输出如下:

["1", "2"]
[1, 2, 3]
(
    1,
    1
)
(
    1,
    1,
    a
)

可以看出,打印 Any 类型的变量时,Swift 实际将 String 类型推导为 Int 类型了。

Swift 中的推导功能,可以推导 Array 的类型,如下代码:

let a = ["a", "b"]
print(a)
    
let b = ["a", "b", nil]
print(b)
    
let c = ["a", "b", 1] as [Any]
print(c)
    
let d = ["a", "b", nil, 1] as [Any?]
print(d)
    
let e = a as! NSMutableArray
let f = b as! NSMutableArray
let g = c as! NSMutableArray
let h = d as! NSMutableArray

打印结果:

["a", "b"]
[Optional("a"), Optional("b"), nil]
["a", "b", 1]
[Optional("a"), Optional("b"), nil, Optional(1)]

但是,可以发现,所有转换为 NSMutableArray 的操作都失败了,报错如下:

Could not cast value of type 'Swift._SwiftDeferredNSArray' (0x10c6be410) to 'NSMutableArray' (0x10c167e08).

但是转换为 NSArray 的操作却是成功的,再对比下面的代码:

var array: NSArray = ["a","b"]
print(array)
print(type(of: array))
let mutableArray = array as! NSMutableArray

var array1: Array<Any> = ["1",1]
print(array1)
print(type(of: array1))
let mutableArray1 = array1 as! NSMutableArray

输出和报错如下:

(
    a,
    b
)
__NSArrayI
Could not cast value of type '__NSArrayI' (0x104424008) to 'NSMutableArray' (0x104423068).

["1", 1]
Array<Any>
Could not cast value of type 'Swift.__SwiftDeferredNSArray' (0x1115eaaa0) to 'NSMutableArray' (0x1110d6068).

所以,在 Swift 中,不论是 Array 类型,还是 NSArray 类型,都是是无法转换为 NSMutableArray 类型的。

发布了129 篇原创文章 · 获赞 23 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/u011374318/article/details/100086125