tft每日頭條

 > 生活

 > swift變量後加大括号什麼意思

swift變量後加大括号什麼意思

生活 更新时间:2025-01-16 00:07:19

swift變量後加大括号什麼意思?摘要iOS 開發,尤其是從 OC 轉換到 Swift,對 Array 需要重新了解,Swift 中保留了什麼屬性,增加了什麼屬性,内存存儲是什麼情況等等,了解了這些,在使用 Array 的時候可以更符合 Swift 的思想,也方便了自己,接下來我們就來聊聊關于swift變量後加大括号什麼意思?以下内容大家不妨參考一二希望能幫到您!

swift變量後加大括号什麼意思(Swift-技巧七重識)1

swift變量後加大括号什麼意思

摘要

iOS 開發,尤其是從 OC 轉換到 Swift,對 Array 需要重新了解,Swift 中保留了什麼屬性,增加了什麼屬性,内存存儲是什麼情況等等,了解了這些,在使用 Array 的時候可以更符合 Swift 的思想,也方便了自己。

Array 是應用程序中最常用的數據類型之一,可以使用 Array 來處理應用程序中的數據。使用 Array 類型來保存單一類型的元素。數組可以存儲任何類型的元素—— 從 Int 到 String,甚至是 Class,但是數組中元素必須是同一類型

Swift 中可以使用數組字面量創建數組,若沒有定義數組中元素類型,Swift 會自動推斷數組中元素的類型。例如:

// 數組元素類型為 Int let numbers = [1, 2, 3] // 數組元素類型為 String let names = ["li", "zhang"]

也可以通過在聲明中指定數組的元素類型來創建一個空數組,例如:

// 元素類型為 Int 的空數組 var emptyInt: [Int] = [] // 元素烈性為 Double 的空數組 var emptyDouble: Array<Double> = Array()

如果需要固定數量的默認值來初始化數組,可以使用 Array(repeating:count:) 創建:

var digitCounts = Array(repeating: 1, count: 3) print(digitCounts) // Prints "[1, 1, 1]"

訪問數組元素

當需要對數組所有元素執行操作時,可以使用 for-in 來循環遍曆數組的内容。

for name in names { print(name) } // Print "li" // Print "zhang"

這裡可以使用 isEmpty 屬性快速檢查數組中是否包含任何元素,等同于使用 count 屬性查找數組中的元素數量,并判斷是否為 0

print(numbers.isEmpty) // Print false print(numbers.count == 0) // Print false

使用 first 和 last 屬性可以安全地訪問數組的第一個元素和最後一個元素,如果數組為空,就返回 nil

print(number.first) // Print "1" print(number.last) // Print "3" print(emptyInt.first, emptyInt.last, separator: ", ") // Prints "nil, nil"

可以通過下标訪問數組中的單個元素,非空數組的第一個元素下标為 0,數組的下标範圍從 0 到數組的 count(不包括 count)。使用負數、等于或者大于 count 的索引,會引發運行時錯誤,比如:

print(number[0], number[2], separator: ", ") // Prints "1, 3" print(emptyInt[0]) // Triggers runtime error: Index out of range

添加和删除元素

假如你需要存儲一個入職員工的名字列表。在這期間,你需要添加和删除名字。

var staffs = ["zhang", "wang", "li"]

使用 append(_:) 方法将單個元素添加到數組的尾部。使用 append(contentsOf:) 可以同時添加多個元素,參數可以是另外一個數組或者元素類型相同的序列

staffs.append("zhao") staffs.append(contentsOf: ["song", "suo"]) // ["zhang", "wang", "li", "zhao", "song", "suo"]

你也可以在數組中間添加新的元素,使用 insert(_:at:) 函數插入單個元素,使用 insert(contentsOf:at:) 方法插入另一個集合或者數組字面量的多個元素。索引處和索引後面的元素都往後移,騰出空間。

staffs.insert("ding", at: 3) // ["zhang", "wang", "li", "ding", "zhao", "song", "suo"]

要從數組中删除元素,可以使用 remove(at:)、removeSubrange(_:) 和 removeLast() 函數。

staffs.remove(at: 0) // ["wang", "li", "ding", "zhao", "song", "suo"] staffs.removeLast() // ["wang", "li", "ding", "zhao", "song"]

通過将新值賦值給下标,達到用新值替換現有的元素的效果

if let i = staffs.firstIndex(of: "ding") { staffs[i] = "bian" } // ["wang", "li", "bian", "zhao", "song"]

增加數組的大小(重點)

每個數組都會保留特定數量的内存來保存其内容。當向數組中添加元素時,該數組超過其預留的容量,該數組就會分配更大的内存空間,并将它的所有元素賦值到新的存儲空間。添加一個元素的時間是固定的,相對來說性能是平均的。但是重新分配的操作會帶來性能成本,随着數組的增大,這些操作發生的頻率也會越來越低。

如果知道大約需要存儲多少元素,在添加到元素之前使用 reserveCapacity(_:) 函數,避免中間重新分配。使用 count 和 capacity 屬性來确定數組在不分配更大存儲空間的情況下還可以存儲多少元素。

var array = [1, 2] array.reserveCapacity(20)

對于大多數 Element 類型的數組,存儲區域是一個連續的内存,對于元素類型是 class 或者 objc protocol 類型的數組,該存儲可以是一個連續的内存,或者 NSArray 的實例。因為 NSArray 的任何子類都可以是一個 Array,所以這種情況下不能保證是内存塊或者 NSArray 的實例

修改數組副本(重點)

每個數組都有一個獨立的存儲空間,存儲着數組中包含的所有元素的值。對于簡單類型,如整數或者其他結構,當更改一個數組中的值時,該元素的值不會在數組的任何副本中更改。例如:

var numbers = [4, 5, 6] var numberscopy = numbers numbers[0] = 9 print(numbers) // Prints "[9, 5, 6]" print(numbersCopy) // Prints "[4, 5, 6]"

如果數組的元素是類的實例。在本例中,存儲在數組中的值是對存在于數組之外的對象引用。如果更改一個數組中對象的引用 ,則隻有該數組有對新對象的引用。但是,如果兩個數組包含對同一個對象的引用,則可以從兩個數組中看到該對象屬性的更改,例如:

class InterR { var value = 10 } var integers1 = [InterR(), InterR()] var integers2 = integers1 integers1[0].value = 100 print(integers2[0].value) // Prints "100" integers1[0] = InterR() print(integers1[0].value) // Prints "10" print(integers2[0].value) // Prints "100"

和标準庫中的所有可變大小集合一樣,數組也使用 copy-on-write 優化。多個副本共享同一個存儲空間,直到修改其中一個副本為止。當發生這種情況時,被修改的數組會創建新的存儲空間存儲,然後在對應的位置修改。copy-on-write 優化可以減少複制的數量。

這就說明,如果一個數組與其他副本共享存儲空間,對該數組的第一次更改操作會導緻複制該數組的成本。之後就可以作為唯一的擁有者來對它進行操作。

下面例子中,将創建一個數組和兩個共享相同存儲的副本。當原始數組被修改時,它會在修改前對其存儲進行唯一複制。然後進行修改。而兩個副本繼續共享原來的存儲空間。

var numbers = [7, 8, 9] var copy1 = numbers var copy2 = numbers numbers[0] = 100 numbers[1] = 200 numbers[2] = 300 // numbers: [100, 200, 300] // copy1 和 copy 2 : [7, 8, 9]

Array 和 NSArray 之間轉換(重點)

當需要訪問 NSArray 實例的 API 時,使用類型轉換操作符 as 來轉換 Array 實例。為了保證轉換成功,數組的 Element 類型必須是一個 class 類型,一個 @objc protocol 或者一個連接到 Foundation 類型。

下面例子展示了如何使用 write(to:atomically:) 函數将一個 Array 實例連接到 NSArray。在這個例子中,colors 數組可以轉換到 NSArray,因為 colors 數組的 String 類型元素轉換到 NSString。另一個,編譯器阻止轉換 moreColors 數組,因為它的 Element 類型是 Optional<String>, 它不能轉換 Foundation 類型。

let colors = ["periwinkle", "rose", "moss"] let moreColors: [String?] = ["ochre", "pine"] let url = URL(fileURLWithPath: "names.plist") (colors as NSArray).write(to: url, atomically: true) // true (moreColors as NSArray).write(to: url, atomically: true) // error: cannot convert value of type '[String?]' to type 'NSArray'

如果數組的元素已經是 class 或 @objc protocol 的實例,那麼從 Array 到 NSArray 的轉換隻需要 O(1) 時間和空間,否則,它需要 O(n) 個時間和空間

當目标數組的元素類型是一個 class 或 @objc protocol 時,從 NSArray 到 Array 的轉換首先調用數組上的 copy(with:) 函數來得到一個不可變的副本,然後執行額外的 Swift bookkeeping work,需要 O(1) 時間。對于已經不可變的 NSArray 實例,copy(with:) 通常在 O(1) 時間内返回相同的數組,否則,複制性能将不确定。如果 copy(with:) 返回相同的數組,NSArray 和 Array 的實例使用相同的 copy-on-write 優化共享存儲空間,當兩個 array 實例共享存儲空間時,使用相同的優化。

當目标數組的元素類型是轉換 Foundation 類型的非 class 類型時,從 NSArray 到 Array 的轉換會在 O(n) 時間内把元素轉換複制到連續的存儲空間。比如,從 NSArray 轉換到 Array<Int> 執行這樣的複制。當訪問 Array 實例的元素時,不需要進一步的轉換。

注意

ContiguousArray 和 ArraySlice 類型沒有轉換,這些類型的實例總是有一個連續的内存空間作為它的的存儲。

題外話

時間倉促,說的東西可能不全面,在你查看的過程中遇到什麼問題,評論區給我留言,我會盡快回複

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved