2012-08-09 120 views
4

我試圖將NSString值從NSMutableArray複製到一個新變量中。 NSString stringWithString返回NSString與我的數組中的對象具有相同的內存地址。爲什麼?爲什麼NSString stringWithString返回指向複製字符串的指針?

#import <Foundation/Foundation.h> 

int main(int argc, const char * argv[]) 
{ 

    @autoreleasepool { 

     NSMutableArray *arr = [NSMutableArray arrayWithObject:@"first"]; 

     NSLog(@"string is '%@' %p", [arr objectAtIndex:0], [arr objectAtIndex:0]); 

     // copy the string 
     NSString *copy = [NSString stringWithString:[arr objectAtIndex:0]]; 
     NSLog(@"string is '%@' %p", copy, copy); 

    } 
    return 0; 
} 
+1

不知道爲什麼會發生這種情況,但是您是否嘗試過'NSString * copy = [[arr objectAtIndex:0] copy];' – Ecarrion 2012-08-09 19:47:38

+0

我有,它有相同的結果 - 內存地址匹配。 – joshuapoehls 2012-08-09 19:54:08

+0

我需要這樣做的原因是因爲在我的真實應用程序中,該數組作爲參數傳遞給我的方法,並在稍後處理。當它被丟棄時,即使我已經將它「複製」出陣列,我也正在丟失我的NSString。 – joshuapoehls 2012-08-09 19:55:30

回答

7

1)無論何時使用@""語法創建字符串,框架都會自動緩存該字符串。 NSString是一個非常特殊的類,但框架會照顧它。當您在應用程序的多個位置使用@"Some String"時,它們都將指向內存中的相同地址。只有當你使用類似-initWithData:encoding的東西時,字符串纔會被緩存。

2)其他答案建議您應該使用-copy來代替,但-copy只會創建對象的副本,如果該對象是可變的。 (比如NSMutableString)
當你發送-copy到一個不可變的對象(比如NSString)時,它將和發送-retain一樣返回對象本身。

NSString *originalString = @"Some String"; 
NSString *copy = [originalString copy]; 
NSString *mutableCopy1 = [originalString mutableCopy]; 
NSString *mutableCopy2 = [mutableCopy copy]; 
NSString *anotherString = [[NSString alloc] initWithString:originalString]; 

- >originalStringcopymutableCopy2anotherString將全部指向同一個內存地址,只mutableCopy1點做存儲不同的區域。

+0

@Fabain如果是這種情況,那麼如果我們對* copy變量的值進行任何更改,爲什麼這個更改不會反映* originalString值。 – 2017-03-24 10:43:27

+0

@i_Intiution不能對不可變對象進行更改。 – 2017-06-22 06:27:13

4

由於NSString實例是不可變的,該方法+stringWithString:簡單地用遞增的引用計數返回輸入字符串。

如果你真的要強制一個新的,相同的字符串的創建,請嘗試:

NSString * copy = [NSString stringWithFormat:@"%@", [arr objectAtIndex:0]]; 

那裏有小點這樣做,不過,除非你需要的指針是一些獨特的其他原因...