swift的深、淺拷貝
前言:Swift相對應Objective C來說,它不再需要絕大部分物件繼承自NSObject
,所以Swift的型別和Objective C的變數型別也不一致。
Value Type/Reference Type
什麼是值型別,引用型別?
二者最主要的差別在於當copy發生的時候,注意,當在Swift中使用賦值符號的時候發生的都是copy,這個在最後我會解釋為什麼。
Struct是值型別
struct S{
var num = -1
}
var a = S()
var b = a
a.num = 10
print(b.num) //-1
可以看到,值型別拷貝後的記憶體是這個樣子的
再來看看引用型別
class S{
var num = -1
}
var a = S()
var b = a
a.num = 10
print(b.num) // 10
總結
值型別或者引用型別在賦值的時候都是Copy,值型別拷貝累實際的記憶體(value),而飲用型別只是拷貝了指標,仍然指向最開始的記憶體區域
什麼是值型別or 引用型別?
- Class的例項是引用型別
- Swift方法型別是引用型別(在Swift中,方法也是一種型別)
- 其餘的都是值型別,像Array,Dictionary本質都是Struct。
值型別的優點
優點還是很明顯的,每次得到的都是一個Copy,這樣就可以放心的執行,沒必要擔心其他程式碼修改這個值。尤其是在多執行緒環境裡。
值型別每次都會進行Copy嗎?
並不是每次都是要copy的,當值並不會改變的時候,Swift並不會進行copy。例如
let a = 1;let b = a
.
什麼時候用值型別/引用型別?
用值型別
- 當你希望用
==
來比較的時候 - 賦值後有獨立的狀態
- 資料在多執行緒中使用
引用型別
- 當你希望用
===
來比較的時候(注意,這裡三個等號) - 建立共享的可變資料
Copy/MutableCopy
對於不可變型別,舉例NSString
程式碼
let str1 = NSString(string: "123")
let str2 = str1.copy() as! NSString
let str3 = str1.mutableCopy() as ! NSMutableString
NSLog("最初: %p", str1)
NSLog("copy: %p", str2)
NSLog("mutableCopy: %p", str3)
可以看到Log
2015-12-01 12:07:41.861 SWTest[1082:40543] 最初: 0x7fd1d3d74cb0
2015-12-01 12:07:41.862 SWTest[1082:40543] copy: 0x7fd1d3d74cb0
2015-12-01 12:07:41.862 SWTest[1082:40543] mutableCopy: 0x7fd1d3d18c80
可以看到,對於不可變型別
- copy 是淺拷貝,只拷貝指標
- mutableCopy 是深拷貝,拷貝了value
對於可變型別,舉例NSMutableString
let str1 = NSMutableString(string: "123")
let str2 = str1.copy() as! NSString
let str3 = str1.mutableCopy() as! NSMutableString
NSLog("最初: %p", str1)
NSLog("copy: %p", str2)
NSLog("mutableCopy: %p", str3)
- 可以看到Log
2015-12-01 12:10:35.721 SWTest[1113:43822] 最初: 0x7fba89e8a850
2015-12-01 12:10:35.721 SWTest[1113:43822] copy: 0xa000000003332313
2015-12-01 12:10:38.006 SWTest[1113:43822] mutableCopy: 0x7fba89e8a960
可以看到,對於可變型別
- copy 深拷貝,拷貝了value
- mutableCopy 是深拷貝,拷貝了value
對於不可變集合
線寫一個輔助方法,列印NSArray中物件指向的地址
func logArrayElementPointAdderss(array:NSArray,description:String){
for element in array{
let object = element as! NSObject
NSLog("%@: %p", description,object)
}
}
- 然後
let array = NSArray(arrayLiteral: NSString(string: "123"),NSNumber(int: 12))
let array1 = array.copy() as! NSArray
let array2 = array.mutableCopy() as! NSMutableArray
NSLog("最初: %p", array)
NSLog("copy: %p", array1)
NSLog("mutableCopy: %p", array2)
logArrayElementPointAdderss(array, description: "最初")
logArrayElementPointAdderss(array1, description: "copy後")
logArrayElementPointAdderss(array2, description: "mutableCopy後")
看看Log
2015-12-01 12:18:46.252 SWTest[1156:50909] 最初: 0x7f9c304afcb0
2015-12-01 12:18:46.253 SWTest[1156:50909] copy: 0x7f9c304afcb0
2015-12-01 12:18:46.253 SWTest[1156:50909] mutableCopy: 0x7f9c30403980
2015-12-01 12:18:46.255 SWTest[1156:50909] 最初: 0x7f9c304b4d30
2015-12-01 12:18:46.255 SWTest[1156:50909] 最初: 0xb0000000000000c2
2015-12-01 12:18:46.255 SWTest[1156:50909] copy後: 0x7f9c304b4d30
2015-12-01 12:18:46.256 SWTest[1156:50909] copy後: 0xb0000000000000c2
2015-12-01 12:18:46.256 SWTest[1156:50909] mutableCopy後: 0x7f9c304b4d30
2015-12-01 12:18:46.256 SWTest[1156:50909] mutableCopy後: 0xb0000000000000c2
可以看到,對於不可變集合
- 對於集合本身,Copy只是拷貝了指標,指標仍然指向最初的Array物件
- 對於集合本身,MutableCopy拷貝了value
- 對於集合中儲存的物件,不管是copy還是mutableCopy,都是淺拷貝。
畫個圖加深理解
對於NSArray的Copy
對於NSArray的MutableCopy
對於可變集合
let array = NSMutableArray(arrayLiteral: NSString(string: "123"),NSNumber(int: 12))
let array1 = array.copy() as! NSArray
let array2 = array.mutableCopy() as! NSMutableArray
NSLog("最初: %p", array)
NSLog("copy: %p", array1)
NSLog("mutableCopy: %p", array2)
logArrayElementPointAdderss(array, description: "最初")
logArrayElementPointAdderss(array1, description: "copy後")
logArrayElementPointAdderss(array2, description: "mutableCopy後")
可以看到Log
2015-12-01 12:31:22.818 SWTest[1209:61916] 最初: 0x7f937ad73d90
2015-12-01 12:31:22.818 SWTest[1209:61916] copy: 0x7f937ad91fb0
2015-12-01 12:31:22.819 SWTest[1209:61916] mutableCopy: 0x7f937ad73190
2015-12-01 12:31:22.819 SWTest[1209:61916] 最初: 0x7f937ac0c100
2015-12-01 12:31:22.820 SWTest[1209:61916] 最初: 0xb0000000000000c2
2015-12-01 12:31:22.820 SWTest[1209:61916] copy後: 0x7f937ac0c100
2015-12-01 12:31:22.820 SWTest[1209:61916] copy後: 0xb0000000000000c2
2015-12-01 12:31:22.820 SWTest[1209:61916] mutableCopy後: 0x7f937ac0c100
2015-12-01 12:31:22.820 SWTest[1209:61916] mutableCopy後: 0xb0000000000000c2
可以看到,對於可變集合
- 對於集合本身,Copy拷貝了value
- 對於集合本身,MutableCopy拷貝了value
- 對於集合中儲存的物件,不管是copy還是mutableCopy,都是淺拷貝
最後
歡迎關注Leo的CSDN部落格,我會持續更新iOS/Objective C/Swift相關的部落格
相關推薦
swift的深、淺拷貝
前言:Swift相對應Objective C來說,它不再需要絕大部分物件繼承自NSObject,所以Swift的型別和Objective C的變數型別也不一致。Value Type/Reference Type什麼是值型別,引用型別?二者最主要的差別在於當copy發生的時候,
python按引用賦值和深、淺拷貝
按引用賦值而不是拷貝副本 在python中,無論是直接的變數賦值,還是引數傳遞,都是按照引用進行賦值的。 在計算機語言中,有兩種賦值方式:按引用賦值、按值賦值。其中按引用賦值也常稱為按指標傳值(當然,它們還是有點區別的),後者常稱為拷貝副本傳值。它們的區別,詳細內容參見:按值傳遞 vs. 按指標傳遞。
=、淺拷貝、深拷貝小結
使用 deepcopy spa 不同 logs 內存 color 但是 引用 >>> import copy // = 指向同一個內存空間,操作的是同一個對象 >>> t1 = {‘a‘:1, ‘b‘:2} >>>
Python 深拷貝、淺拷貝
地址 pre 產生 字典 deep 可能 新的 之間 append Python中,對象的賦值,拷貝(深/淺拷貝)之間是有差異的,如果使用的時候不註意,就可能產生意外的結果。 首先,對賦值操作我們要有以下認識: 賦值是將一個對象的地址賦值給一個變量,讓變量指向該地址( 舊
賦值、淺拷貝以及深拷貝的區別
fff 情況 spa clas nbsp tro 淺拷貝 pen pan 字符串賦值 >>> >>> str1 = ‘standby‘ >>> >>> str2 = str1 &g
09_Python深拷貝、淺拷貝
dict 出現 ngs error col spa 是把 runtime 其中 一、循環列表,刪除其中的元素 l1 = [1,2,3,4,5,6,7] 循環刪除奇數位元素 1.正序循環刪除,會出現越界情況,所以采用倒敘的方式刪除 1 l1 = [1,2,3,4,5,6,
Python賦值、淺拷貝、深拷貝的區別
ID IV 元素 改變 拷貝 但是 int 需要 copy 一、賦值 str例子 >>> a = 'hello' >>> b = 'hello' >>> c = a >>&
c++拷貝構造函數(深拷貝、淺拷貝)——轉
完全復制 pla isp std c++ 必須 spa 例如 成員 拷貝構造函數: 拷貝構造函數是一種特殊的構造函數,函數的名稱必須和類名稱一致,它的唯一的一個參數是本類的一個引用變量,該參數是const類型,不可變的。例如:類A的拷貝構造函數的形式為A(A& x)
深拷貝、淺拷貝
遞歸 col bsp ima span .com 分享 pen 淺拷貝 深拷貝、淺拷貝 1. 淺拷貝 淺拷貝是對於一個對象的頂層拷貝 通俗的理解是:拷貝了引用,並沒有拷貝內容 2. 深拷貝 深拷貝是對於一個對象所有層次的拷貝(遞歸)
python 字典賦值、淺拷貝、深拷貝
# 專案開發中,因字典可修改,所以注意拷貝方式 import copy 1. 原字典操作 dict1 = {'user': 'test', 'num': [1, 2, 3]} &
python基礎-深拷貝、淺拷貝
一、“==”和 is “==”是比較兩個物件是否相等,而不管是不是指向同一個地址 is 是指不僅物件相等,而且指向的記憶體地址也相等。。(小整數物件池除外) 二、淺拷貝和深拷貝 淺拷貝:a = [
Python中賦值、淺拷貝與深拷貝的區別
賦值,其實就是物件的引用,對新物件的如何修改都會影響到原始物件。 Python中有兩種拷貝操作:淺拷貝和深拷貝。 copy.copy(x):返回x的淺拷貝。 copy.deepcopy(x):返回x的深拷貝。 那麼都是拷貝,淺拷貝和深拷貝有什麼不同嗎? 淺
python學習(六):python中賦值、淺拷貝、深拷貝的區別
存在賦值、淺拷貝、深拷貝問題的資料型別是對組合物件來說,所謂的組合物件就是包含了其它物件的物件,如列表,類例項。 其他的單個物件則不存在這個問題。 可變物件: list, dict. 不可變物件有: int, string, float, tuple.  
深拷貝、淺拷貝區別,實現深拷貝的方法
如何區分深拷貝與淺拷貝,簡單點來說,就是假設B複製了A,當修改A時,看B是否會發生變化,如果B也跟著變了,說明這是淺拷貝,拿人手短,如果B沒變,那就是深拷貝,自食其力。 此篇文章中也會簡單闡述到棧堆,基本資料型別與引用資料型別,因為這些概念能更好的讓你理解深拷貝與淺拷貝。 我們來舉個淺拷貝例
深拷貝、淺拷貝、賦值介紹
1.賦值,深拷貝,淺拷貝: 賦值是多個物件指向同一個記憶體空間,多個物件共同操作同一個資料 拷貝是對記憶體資料的複製,目的是能夠單獨的修改資料 1.賦值: 物件之間的賦值本質上是物件之間的引用傳遞,也就是多個物件指向同一個
深入理解Javascript中的堆與棧、淺拷貝與深拷貝
Javascript中的淺拷貝與深拷貝 先從JavaScript的資料型別存放的位置堆疊開始說吧 什麼是堆疊? 我們知道計算機領域中堆疊是兩種資料結構,它們只能再一端(稱為棧頂(top))對資料項進行插入和刪除。 堆:佇列優先,先進先出,由作業系統自動分配釋放,存放函式的引數值,區域性變數的
Python中的複製、淺拷貝與深拷貝
1.物件的三要素 id、type以及value,id唯一標識一個物件,相當於地址,id一樣,說明就是同一個東西。type和value就是字面意思。 2.==和is ==比較的是value,is比較的是id,意思是 “是否為同一個物件”,條件比==要嚴格。 3.可變物
賦值、淺拷貝和深拷貝的區別?
首先要知道變數,物件,引用三者之間的關係 變數: 是一個元素, 擁有指向物件的連線空間 **物件:**被分配的一塊記憶體,儲存代表的值 引用: 是變數到物件的指標 一、賦值 在 Python 中,物件的賦值就是簡單的物件引用, 如下所示: a = [1,2,
python 拷貝、淺拷貝、深拷貝之間的聯絡
import copy #淺拷貝與深拷貝 #*************************************************** #*************************************************** #**
python賦值、淺拷貝、深拷貝區別
閱讀目錄 在寫Python過程中,經常會遇到物件的拷貝,如果不理解淺拷貝和深拷貝的概念,你的程式碼就可能出現一些問題。所以,在這裡按個人的理解談談它們之間的區別。 回到頂部 一、賦值(assignment) 在《Python FAQ1》一文中,對賦值已經講的很清楚