結構體和類
5.4寫時複製
定義:結構體的引用在改變的一瞬間是唯一的,不會有複製發生,記憶體的改變將在原地進行。
不太好理解的話我們一起看下面這個demo
var x = [1,2,4]
var y = x
x.append(5) //1,2,4,5
y.removeLast() //1,2
複製程式碼
這時,把x賦值給y時會發生複製。這時候兩個陣列的引用
指向的是記憶體中的同一個位置
。共享儲存部分。
當改變x
時這個共享會被檢查到。
記憶體將會被複製出來。
我們就獨立的改變了兩個變數。
耗效能的元素複製操作只會在必要的時候
傳送。這個就叫做寫時複製
。
####通俗來說: 複製時用的是一個記憶體地址,當某一個集合改變時恰到好處的複製了一份出來。
已經用官方
,非官方
,簡潔
的語句解釋了三遍了朋友我相信你肯定懂的!
知識點: 複製結構體變數。裡面進行的淺複製。物件本身不會被複制。只有引用會被複制。
寫時複製的高效方法
1.首先要知道一個物件是否是唯一引用的,通過isKnownUniquelyReferenced(&obj)函式來獲取。
//會返回一個Bool值告訴你是否唯一 對於OC的物件直接返回false
isKnownUniquelyReferenced(&object: T)
final class Box<A> {
var unbox:A
init(_ value:A) {
self.unbox = value
}
}
var a = Box(NSMutableData())
isKnownUniquelyReferenced(&a)//true
var b = a
isKnownUniquelyReferenced(&a)//false
isKnownUniquelyReferenced(&b)//false
複製程式碼
2.然後判斷為false時執行寫是複製(這裡詳讀了一遍感覺比較艱深晦澀,大家可在參考下面的Demo理解)。
struct MyData {
fileprivate var _data: Box<NSMutableData>
var _dataForWriting: NSMutableData {
mutating get {
if !isKnownUniquelyReferenced(&_data) {//檢查對_data的引用是否是唯一性
_data = Box(_data.unbox.mutableCopy() as! NSMutableData)
print("Making a copy")
}
return _data.unbox
}
}
init(_ data: NSData) {
self._data = Box(data.mutableCopy() as! NSMutableData)
}
}
extension MyData {
mutating func append(_ other: MyData) {
_dataForWriting.append(other._data.unbox as Data)
}
}
let someBytes = MyData(NSData(base64Encoded: "wAEP/w==", options: [])!)
var empty = MyData(NSData())
var emptyCopy = empty
for _ in 0..<5 {
empty.append(someBytes)
}
empty // <c0010fff c0010fff c0010fff c0010fff c0010fff>
emptyCopy // <>
複製程式碼