iOS 指针和内存块

在OC中如果不注意指针内存块的问题,你可能会遇到一些很奇怪的问题,但是却很难解决,本文将解释一些在OC中你可能需要了解的知识点。

我们来看这段代码:

    NSMutableString *str = [@"string1" mutableCopy];
    NSMutableString *str2 = str;
    [str appendString:@"__str"];
    [str appendString:@"__str2"];
    NSLog(@"str1:%@    str2:%@",str,str2);



    //输出:str1:string1__str__str2    str2:string1__str__str2

我们可以看到str1和str2已经是相同的,因为

    NSMutableString *str2 = str;

这段代码让str2指向了str1的内存块,也就是说str1和str2现在是对同一块内存的两个指向,你可以说他们是一模一样的,我们来验证这一点:

    NSLog(@"str1:%X  str2:%X",str,str2);
//输出:str1:B3D96B60  str2:B3D96B60

我们打印了str和str2的内存块,我们发现的确是一模一样的。


但很多时候我们希望得到的是一个新的对象,那么这个时候我们可以使用“copy,mutableCopy”语法,copy得到一个不可变变量,mutableCopy得到一个可变变量。
像这样:

  NSMutableString *str = [@"string1" mutableCopy];
    NSMutableString *str2 = [str mutableCopy];
    [str appendString:@"__str"];
    [str appendString:@"__str2"];
    NSLog(@"str1:%X  str2:%X",str,str2);
    
  //输出:str1:92F36240  str2:92F36A90

我们用str copy出一个新的对象,然后打印了他们的地址,发现的确是新的一个内存块了。


在这里我们需要注意,所有的字面量语法都是开辟出一个新的内存块,包括@"",@[],@{}。
也就是说:

@"" 与[[NSString alloc]init];等价
@[] 与[[NSArray alloc]init];等价
@{} 与[[NSDictionary alloc]init];等价

[@"" mutableCopy]; 与[[NSMutableString alloc] init];等价
[@[] mutableCopy]; 与[[NSMutableArray alloc] init];等价
[@{} mutableCopy]; 与[[NSMutableDictionary alloc] init];等价

也就是说当我们用字面量语法对一个变量赋值时相当于对他重新开辟了内存块,也就是原本的内存块和他是已经没有关系了。


在这里顺便提一下const修饰符;

    extern NSString * const var;
    extern NSString const * var;

这是两种不一样的写法,结果肯定也是不一样的,区别也是在于内存块和指针。
const修饰符将其后的变量设置为常量。

    extern NSString * const var;

当const在星号后时,var变量的内存指针将不能指向其他内存,同时内存块中的内容也将保持不变。

    extern NSString const * var;

而当const在星号前面时,情况就发生变化了,var变量的内存指针同样无法指向其他内存块,但是在这种情况下,var的内存块的内存是可以发生变化的。
也就是说下面这种操作是允许的:

   NSMutableString const * var = [@"str" mutableCopy];
    [var appendString:@"__var"];
    NSLog(@"var:%@",var);
    //输出:var:str__var

而反过来则是不允许的,关于这部分内容,在本人另一篇文章中有详细的解释:
http://www.strongx.cn/?p=118


更多文章请关注:http://www.StrongX.cn

你可能感兴趣的:(iOS 指针和内存块)