淺談NSString*做為形參傳值

  • 前言

我們知道,在C語言中,基本數據類型做為形參傳遞是無法直接更改其值的,因為是值傳遞,在函數中更改完畢后系統會收回為此函數分配的內存能及里面的局部變量。如果想要更改,可以通過指針,根據地址找到找到對應的值,然后可以更改。

  • 問題

那么問題來了,比如在OC中,拿NSString為特例,我聲明的NSString明明也是NSString* ,并且我傳遞的也是NSString*指針,但是為什么不能更改?代碼如下:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSString *str = @"made";
NSLog(@"1----%p",str);
NSLog(@"2----%p",&str);
[self stringTestChange:str];
NSLog(@"after - %@",str);
}

- (void)stringTestChange:(NSString *)aString{
NSLog(@"3----%p",aString);
NSLog(@"4----%p",&aString);
aString = @"madeChina";
}

上述打印結果:


打印結果

可以看到值并沒有改變,但是從上述打印,我們也可以看到,str與aString的值是相同的,但是你會發現它們的地址去并不相同。

也就是說,在函數中aString是重新分配了內存空間,地址不一樣,但是它們指向的都是同一塊存儲空間,當再賦于新值給aString的時候,只不過是改變了它的指向而已,等函數結束后,原str的指向并未發生任何改變。當執行到打印after時,被改變的指向僅僅是aString,存儲結構大致如下:

圖解一

所以如果想通過函數改變原字符串,需要找到指向str的地址。所以更改如下:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSString *str = @"made";
[self stringTestChange:&str];
NSLog(@"after - %@",str);
}
- (void)stringTestChange:(NSString **)aString{
*aString = @"madeChina";
}

這樣再一打印,是沒問題的。

  • 結論

為什么這樣可以?因為我們首先通過地址找到了str,然后通過*str找到了指向made字符串的指針,然后重新改變了它的指向,最后就修改完成了。
圖示如下:

圖解一

如有問題,希望指出,一起探討交流!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • __block和__weak修飾符的區別其實是挺明顯的:1.__block不管是ARC還是MRC模式下都可以使用,...
    LZM輪回閱讀 3,376評論 0 6
  • 307、setValue:forKey和setObject:forKey的區別是什么? 答:1, setObjec...
    AlanGe閱讀 1,592評論 0 1
  • 1、 OC中與alloc相反的方法是:答案:(C) A、release B、retain C、dealloc ...
    失憶的程序員閱讀 2,887評論 0 6
  • 多線程、特別是NSOperation 和 GCD 的內部原理。運行時機制的原理和運用場景。SDWebImage的原...
    LZM輪回閱讀 2,043評論 0 12
  • 我想我們的關系如同那結扎血管的外科結,到老去的時候都不會脫落! 我不能保證是最好的那個人,但我愿意給你最好的我!
    f5c8833c9a44閱讀 226評論 0 0