<strong>前言
我們在聲明一個nsstring屬性時,對于其內存相關特性,通常有兩種選擇(基于arc環境):strong與copy。那這兩者有什么區別呢?什么時候該用strong,什么時候該用copy呢?讓我們先來看個例子。
代碼驗證
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
@property (nonatomic, strong) nsstring *mystrongstring; @property (nonatomic, copy) nsstring *mycopystring; - ( void )stringtest { nsmutablestring *mutablestr = [nsmutablestring stringwithformat:@ "https://" ]; self.mystrongstring = mutablestr; self.mycopystring = mutablestr; nslog(@ "mutablestr:%p,%p" , mutablestr,&mutablestr); nslog(@ "strongstring:%p,%p" , _mystrongstring, &_mystrongstring); nslog(@ "copystring:%p,%p" , _mycopystring, &_mycopystring); //---------------分割線--------------------- [mutablestr appendstring:@ "devthinking.com" ]; nslog(@ "strongstring:%p,%p" , _mystrongstring, &_mystrongstring); nslog(@ "copystring:%p,%p" , _mycopystring, &_mycopystring); } |
打印日志如下:
1
2
3
4
5
|
2016-11-09 14:14:18.532 democollectoc[92929:1731791] mutablestr:0x60800026fe00,0x7fff549c9be8 2016-11-09 14:14:18.532 democollectoc[92929:1731791] strongstring:0x60800026fe00,0x7ff095402308 2016-11-09 14:14:18.533 democollectoc[92929:1731791] copystring:0x6080004234a0,0x7ff095402310 2016-11-09 14:14:18.533 democollectoc[92929:1731791] strongstring:0x60800026fe00,0x7ff095402308 2016-11-09 14:14:21.039 democollectoc[92929:1731791] copystring:0x6080004234a0,0x7ff095402310 |
結論
1.mystrongstring跟mutablestr的指向地址始終一樣,都為0x60800026fe00,mycopystring跟mutablestr指向的地址不同,即為深copy,新開辟了一份內存;
2.賦值時,當原始字符串是mutable string時,存在此差異,當mutablestr變化時,mystrongstring會隨著改變,而mycopystring則不會。通常我們不想讓其隨著改變,故用copy屬性較多;如果我們想其隨著改變,則用strong。
3. 如果原始賦值字符串為string時,則用copy和strong屬性是一樣的。
變量存儲地址
- &取地址符,取出來的是變量的存儲地址,如mystrongstring mycopystring是存在堆里的,地址以0x7ff09開頭,mutablestr為臨時變量,是存在棧里的,以0x7fff5開頭。
- 直接p打印出來的地址,則是存儲內容實際存在的地址,其實里面存儲的還是地址,詳細的請看下一節,但是我們可以用這個地址區間來判斷存儲的區域。
附:x/3gx查看對象內存
查看基本數據類型的內存時,可直接查看,16進制轉化一下就可以,查看對象時,則不可以,這跟string的結構體是相關的:
以nsstring為例
1
|
nsstring *str = @ "a" ; |
先打印出地址:
1
2
|
(lldb) p str (__nscfconstantstring *) $0 = 0x0000000109b3aa30 @ "a" |
再用x/3gx命令查看內存:
1
2
3
|
(lldb) x/3gx 0x0000000109b3aa30 0x109b3aa30: 0x000000010bf3e348 0x00000000000007c8 0x109b3aa40: 0x0000000109b276db |
再查看0x0000000109b276db中的地址即為字母a的ascii碼實際存在地址:
1
2
|
(lldb) p ( char *)0x0000000109b276db ( char *) $2 = 0x0000000109b276db "a" |
可以直接在變量上右鍵上打開view memory of “*str”, 這就打開memory查看,在address里面輸上0x0000000109b276db,即可查看每個字節的內容。
總結
以上就是這篇文章的全部內容,希望本文的內容對各位ios開發者們能有所幫助,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。