OC基礎—關於不同字符串創建方法創建的字符串的存儲地址的研究

1 摘要

不同字符串創建方法創建的字符串,其內存地址分配原則是不同的,具體的區別看下面的例子。

2 實例代碼



#import "Foundation/Foundation.h"

int main()
{

    NSString *s = @"123";
    NSString *ss = @"1234";

#pragma mark 此二者都是指向@“123"這個字符串常量,所以其地址相同。
    NSString *s1 = [NSString stringWithString:@"123"];
    NSString *s2 = [NSString stringWithString:@"123"];

#pragma mark 重點1:此二者沒有指向@”123“常量,但是同樣的方法創建兩次得到的對象是同一個對象。
    NSString *s3 = [NSString stringWithFormat:@"123"];
    NSString *s4 = [NSString stringWithFormat:@"123"];

    NSLog(@"s= %p, s1= %p, s2= %p, s3= %p, s4= %p", s, s1, s2, s3, s4);

    NSMutableString *sss = @"123";
#pragma  mark 此二者和常量沒有關係,而且同樣的方法創建的兩次得到的對象也不是同一個對象。
    NSMutableString *s5 = [NSMutableString stringWithString:s];
    NSMutableString *s6 = [NSMutableString stringWithString:s];

#pragma  mark 此二者和常量沒有關係,而且同樣的方法創建的兩次得到的對象也不是同一個對象。
    NSMutableString *s7 = [NSMutableString stringWithString:@"123"];
    NSMutableString *s8 = [NSMutableString stringWithString:@"123"];

#pragma  mark 此二者和常量沒有關係,而且同樣的方法創建的兩次得到的對象也不是同一個對象。
    NSMutableString *s9 = [NSMutableString stringWithFormat:@"123"];
    NSMutableString *s10 = [NSMutableString stringWithFormat:@"123"];

    NSLog(@"s= %p, sss= %p, s5= %p, s6= %p, s7= %p, s8= %p, s9= %p, s10= %p", s, sss, s5, s6, s7, s8, s9, s10);

#pragma mark 下面的方法創建的字符串和常量@"1234”無關,但是和編輯之前的字符串佔用相同的內存。
    [s5 appendString:@"4"];
    [s6 appendString:@"4"];

    [s7 appendString:@"4"];
    [s8 appendString:@"4"];

    NSLog(@"ss= %p, s5= %p, s6= %p, s7= %p, s8= %p", ss, s5, s6, s7, s8);

#pragma mark 數組並不遵守上面的規則。
    NSArray *a = @[@1, @2, @3];
    NSArray *aa = @[@1, @2, @3, @4];

#pragma mark 重點2:下面的方法創建的兩個數組佔用不同的內存。
    NSArray *aaa = @[@"12", @"123", @"1234"];
    NSArray *aaaa= @[@"12", @"123", @"1234"];

    NSArray *a1 = [NSArray arrayWithArray:a];
    NSArray *a2 = [NSArray arrayWithArray:a];

    NSArray *a3 = [NSArray arrayWithObjects:@1, @2, @3, nil];
    NSArray *a4 = [NSArray arrayWithObjects:@1,@2, @3, nil];

    NSLog(@"a= %p, aa= %p, aaa= %p, aaaa= %p, a1= %p, a2= %p, a3= %p, a4= %p", a, aa, aaa, aaaa, a1, a2, a3, a4);

#pragma mark 重點3:initwithstring和initwithformat方法具有相同的區別。
/*
     NSString *s = @"123";
     NSString *ss = @"1234";

     #pragma mark 此二者都是指向@“123"這個字符串常量,所以其地址相同。
     NSString *s1 = [[NSString alloc]initWithString:@"123"];
     NSString *s2 = [[NSString alloc]initWithString:@"123"];

     #pragma mark 重點1:此二者沒有指向@”123“常量,但是同樣的方法創建兩次得到的對象是同一個對象。
     NSString *s3 = [[NSString alloc]initWithFormat:@"123"];
     NSString *s4 = [[NSString alloc]initWithFormat:@"123"];

     NSLog(@"s= %p, s1= %p, s2= %p, s3= %p, s4= %p", s, s1, s2, s3, s4);

     NSMutableString *s7 = [[NSMutableString alloc]initWithString:@"123"];
     NSMutableString *s8 = [[NSMutableString alloc]initWithString:@"123"];

     #pragma  mark 此二者和常量沒有關係,而且同樣的方法創建的兩次得到的對象也不是同一個對象。
     NSMutableString *s9 = [[NSMutableString alloc]initWithFormat:@"123"];
     NSMutableString *s10 = [[NSMutableString alloc]initWithFormat:@"123"];

     NSLog(@"s= %p, s7= %p, s8= %p, s9= %p, s10= %p", s, s7, s8, s9, s10);
*/

    return 0;

}

3 總結

  1. 對於nsstring來說:
    1.1 stringwithstring方法創建的字符串與對應的字符串常量佔用相同的內存地址,並且重複調用該方法創建相似的(相同)字符串,其內存地址相同且與對應的字符串常量相同。
    1.2 stringwithformat方法創建的字符串和對應的字符串常量佔用不同的內存地址,並且重複調用該方法創建相似的(相同)字符串,其內存地址相同,但是與對應的字符串常量不相同。
  2. 對於nsmutablestring來說:
    stringwithstring和stringwithformat方法創建的字符串與對應的字符串常量佔用不相同的內存地址,並且重複調用該方法創建相似的(相同)字符串,其內存地址不相同,與對應的字符串常量也相同。
  3. initwithstring和initwithformat方法具有相同的區別。
  4. 數組不適用上面的規則,就算重複創建相似的(相同)的常量,其內存地址也是不同的。

4 待完善

  1. 僅僅知道了這個現象,還沒有弄清楚其原因?
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章