iOS 指针和内存块

作者: StrongX | 来源:发表于2016-05-07 15:44 被阅读1560次

在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 指针和内存块

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

  • 4-1 内存管理

    1.内存布局 2.iOS内存管理方案 [isa指针保存了内存管理的信息] 2.iOS内存管理方案 [isa指针...

  • IOS

    一、IOS基础 1、浅拷贝与深拷贝浅拷贝:拷贝对象的指针成员变量和原对象的指针成员变量指向同一块内存空间。深拷贝:...

  • C++ 指针与引用

    指针和引用的区别? 指针是实体,它指向⼀块内存,它的内容是所指内存的地址;引用是某块内存的别名 引用只能在定义时被...

  • 内存管理

    iOS内存管理机制的原理是引用计数,简单来说就是统计一块内存的所有权。当有一个对象或指针指向一块内存时,该内存的引...

  • iOS 深浅拷贝 为什么NSString使用copy

    理解iOS 深浅拷贝 为什么NSString使用copy 浅拷贝: 指针拷贝,复制一个新的指针,只想同一块内存区域...

  • iOS中的野指针、僵尸对象、空指针

    野指针 野指针和空指针是不一样的,空指针没有储存任何的内存地址,而野指针指向的一块内存地址,但是该内存不可用。换句...

  • 空指针与野指针

    注意空指针和野指针的区别:空指针是指向null的指针,没有指任何内存地址。而野指针是,指向了一块内存地址,但是这块...

  • 手撕iOS底层02 -- 分析alloc&init&new

    手撕iOS底层02 -- 分析alloc&init&new OC对象与指针 三个指针变量指向同一块内存空间,p1 ...

  • 链接收藏

    iOS面试题 野指针 使用了释放的内存 内存泄漏 内存没有释放

网友评论

  • LoveY34:关于const的说法貌似有问题吧?
    extern NSString * const var;=>指针变量的指向不可变,但是指向的内容可变
    extern NSString const * var;=>指针变量的指向可变,但是指向的内容不可变
    19227775e981:我也亲自验证了,“extern NSString const * var;=>内存指针同样无法指向其他内存块,但是在这种情况下,var的内存块的内存是可以发生变化的”,可以指向其他内存
  • 24aa22319986:容器对象的拷贝不会拷贝容器里面的内容到新内存,不记得在哪看的了,const和c++中的一样,分对象和指针
  • f132cdc403ad:在使用copy/mutable copy的时候默认的是shallow copy
    StrongX:@吴为所动 具体试试嘛,四种情况,都打印下地址
    f132cdc403ad: @StrongX 我是看Effective OC 2.0里面讲的“ Copying by default for all the collection classes in Foundation is shallow, meaning that only the container is copied, not the data stored within the container.”
    所以才认为是浅拷贝。只是从书面上看到来讲的,没具体测试分析。
    StrongX:@吴为所动 nonono,只有不可变变量加copy才是浅复制,剩下三种情况都是深拷贝,然而在第一种情况下一般来说内容是不变的,所以也没有影响

本文标题:iOS 指针和内存块

本文链接:https://www.haomeiwen.com/subject/patsrttx.html