雨燕採用ARC(自動引用計數)與數組打交道時,它複製延遲陣列,直到其中一個副本被修改:
對於例如:
var a = [1, 2, 3, 4, 5]
let b = a
let c = a // 1
a.append(6) // 2
print(a.count)
print(b.count)
print(c.count)
在上述步驟1中,存在的[1, 2, 3, 4, 5]
在存儲器中,並a
,b
只有一個副本,和c
AR e引用它。
當在步驟2中修改了a
時,Swift給出了a
,數組的新副本以及b
和c
繼續引用原始數組。所以現在在內存中有2個數組的副本。
讓我們看一個更復雜的例子:
class Person: CustomStringConvertible {
let name: String
var friends: [Person] = []
init(name: String) {
self.name = name
}
var description: String { return name }
}
func createFredsFriends() -> [Person] {
let barney = Person(name: "Barney")
let wilma = Person(name: "Wilma")
let betty = Person(name: "Betty")
let friends = [barney, wilma, betty] // 1
return friends
}
func createFred() -> Person {
let fred = Person(name: "Fred")
let friends = createFredsFriends() // 2
fred.friends = friends // 3
return fred
}
let fred = createFred() // 4
print(fred.friends) // [Barney, Wilma, Betty]
在步驟1,創建朋友的陣列。它由本地變量friends
引用。
此引用消失時createFredsFriends()
回報,到陣列的僅參考在步驟2中的陣列已經傳遞的所有權被保持,則通過本地變量friends
。
在步驟3,對陣列的第二個引用已被分配給屬性fred
。
在步驟4中,createFred()
已返回,因此本地變量friends
已消失,不再引用該數組。唯一的參考資料是由變量fred
持有的fred
對象的財產。
所以陣列創建一次,創建了它幾次提到,並在年底有一個單一的參考陣列和所有這一切都沒有一個單一的複製操作完成。
由於夫特陣列是值類型和複製時改變,則不能傳遞數組,然後期望當複製是要更新的原始。如果您需要這種功能級別,則可以爲該數組創建一個類封裝器,然後通過該類的實例始終訪問該數組。
在這裏,我已經修改了前面的例子來說明如何將工作:
// Class to wrap array so that everyone references the same copy
class FriendsWrapper {
var friends: [Person]
init(friends: [Person]) {
self.friends = friends
}
}
class Person: CustomStringConvertible {
let name: String
var friendsWrapper: FriendsWrapper?
init(name: String) {
self.name = name
}
func addFriend(friend: Person) {
if let wrapper = friendsWrapper {
wrapper.friends.append(friend)
} else {
friendsWrapper = FriendsWrapper(friends: [friend])
}
}
var description: String { return name }
}
func createFredsFriends() -> [Person] {
let barney = Person(name: "Barney")
let wilma = Person(name: "Wilma")
let betty = Person(name: "Betty")
let friends = [barney, wilma, betty]
return friends
}
func createFred() -> Person {
let fred = Person(name: "Fred")
let friendsWrapper = FriendsWrapper(friends: createFredsFriends())
fred.friendsWrapper = friendsWrapper
// Add friend to Fred object
fred.addFriend(Person(name: "Bam Bam"))
// Copy of array in local friendsWrapper is updated
print(friendsWrapper.friends) // [Barney, Wilma, Betty, Bam Bam]
return fred
}
let fred = createFred()
@馬特感謝您的答覆。我沒有明白你的觀點。我需要通過引用來傳遞類別,因爲我不想複製,因爲這是多餘的。我錯了嗎 ? – david
@matt這一行「mainView.categories = categoriesData」它不會將數組複製到另一個數組? – david
@matt它怎麼沒有?請看看這個:http://stackoverflow.com/questions/28889705/in-swift-difference-between-array-vs-nsarray-vs-anyobject,它顯示數組正在傳遞值 – david