NSString字符串创建的内存分配

来源:互联网 发布:sqlserver时间格式化 编辑:程序博客网 时间:2024/05/07 15:53

今天讲到NSString的创建的时候的分配,做实验的时候发现跟教程不一样的地方,如之前的私有方法调用也有差异的现象,可能真的是跟版本有一定关系;贴上代码

 /* 1. 字符串的创建*/

    //创建字符串常量

    NSString* string1 =@"hello";

     

    //创建字符串

    NSString* string2 = [[NSStringalloc]initWithString:@"hello"];

    if(string2 == string1)

        NSLog(@"string2string1指向同一个地址");//这样成功打印出来

    else

        NSLog(@"string2string1指向不相同的地址");

    

    string1 = @"hello world";//这样不算改变,这其实是重新生成了一个字符串,改变指针指向

    NSString* string3 = [[NSStringalloc]initWithFormat:@"hello-%@",string2];

    NSLog(@"string2 == %@", string2);

    NSLog(@"string3 == %@", string3);

   

    NSString* s1 =@"zhangsan";

    NSString* s2 =@"lisi";

    NSString* s3 =@"wangwu";

    //拼接字符串

    NSString* string4 = [[NSStringalloc]initWithFormat:@"%@,%@,%@", s1, s2, s3];

    NSLog(@"string4 == %@", string4);

    

    int age =24;

    NSString* string5 = [[NSStringalloc]initWithFormat:@"%@的年龄是%d", s1, age];

    NSLog(@"string5 == %@", string5);

    

    /* 2. 字符串的比较 */

    NSString* string6 =@"abcd";

    NSString* string7 =@"888888";

    

    if([string6isEqualToString:string7]) {

        NSLog(@"string6 is equal to string7");

    }

    else

        NSLog(@"string6 is not equal to stirng7");

    

    NSString* string8 =@"abc";

    NSString* string9 =@"abc";

    if( string8 == string9) {

        //这里是成功的,由于做了优化,当两个常量都是同样内容时,只存一份就好了

        NSLog(@"string8string9指向同一个地址");

    }

    

    NSString* string10 = [[NSStringalloc]initWithFormat:@"abc%@",@"def"];

    NSString* string11 = [[NSStringalloc]initWithFormat:@"abc%@",@"def"];

    if(string10 == string11) {

        //这里跟教程的不一样,教程是判断为假

        NSLog(@"string10 string11指向同一个地址");

    }

    

    //经调试发现上述情况类似的结果是否指向同一地址并非由initWithFormat决定,而跟format中的字符串长度有关

    //比如下方@“defghij”再减掉一个字符就会指向同一地址,字符再多就是分别开辟的了

    NSString* str10 = [[NSStringalloc]initWithFormat:@"abc%@",@"defghij"];

    NSString* str11 = [[NSStringalloc]initWithFormat:@"abc%@",@"defghij"];

    if(str10 == str11) {

        //这里跟教程的不一样,教程是判断为假

        NSLog(@"str10 str11指向同一个地址");

    }

    

    NSString* string12 = [[NSStringalloc]initWithFormat:@"abc%@",string1];

    NSString* string13 = [[NSStringalloc]initWithFormat:@"abc%@",string1];

    if(string12 == string13) {

        //这里的情况也是,如果把上述format的内容改成string8,比较短,就会进来这个分支,

        NSLog(@"string12 string13指向同一个地址");

        NSLog(@"string12 is pointer to %p",string12);

        NSLog(@"string13 is pointer to %p",string13);

    }

    else {

        //string1换成比较长的字符串时就会进来这个分支

        NSLog(@"string12 string13指向不同的地址");

        NSLog(@"string12 is pointer to %p",string12);

        NSLog(@"string13 is pointer to %p",string13);

    }

    

    //这里查看指针内存显示string14string15指向同一内存,跟教程一样,后面打印一下

    NSString* string14 = [[NSStringalloc]initWithString:@"abc"];

    NSString* string15 = [[NSStringalloc]initWithString:@"abc"];

    if( string14 == string15) {

        NSLog(@"string14string15指向同一地址");

    }

    NSString* str14 = [[NSStringalloc]initWithString:@"abcdefghijklmnopqrstuvwxyz"];

    NSString* str15 = [[NSStringalloc]initWithString:@"abcdefghijklmnopqrstuvwxyz"];

    if( str14 == str15) {

        //这里不论参数的字符串常量多长,都会进来

        NSLog(@"str14str15指向同一地址");

    }

    

以上说明:

1. 根据sdk以及编译器的版本不同,可能编译的时候做的优化也会不同,这跟语言本身可能无关;

2.就我目前所用版本而言

a.如果使用initWithString方式创建字符串的时候参数一样结果就会指向同一个地址;

               b. 对initWithFormat而言并非如教程说的那样一定会创建两个地址;而是根据拼接字符串的长度来决定是否进行优化

这可能没什么用,需要了解的是第一点:程序分配内存的时候是否进行优化以及优化程度,可能并不是很固定的,这点没有太多的研究,不敢乱下结论;

疑惑的是,教程说使用字符串常量赋值方式创建字符串是在常量区分配空间;而用alloc方式创建字符串应该是在堆区分配空间;如string1和string2的创建:

NSString* string1 = @"hello";//常量直接赋值,教程说这会在常量区分配空间

NSString* string2 = [[NSString allocinitWithString:@"hello"];//alloc方式,教程说应该在堆区创建

//但是比较地址却是指向的同一个地址,那是指向常量区了吗?    

if(string2 == string1)

        NSLog(@"string2string1指向同一个地址");//这样成功打印出来

    else

        NSLog(@"string2string1指向不相同的地址");



0 0
原创粉丝点击