• [objectivec]关于内存


        NSString *str = [NSString stringWithString:[[NSString alloc] initWithFormat:@"123"]];
        int i= [str retainCount]; //2 方法中套init,套用的init不会自动release
        
        NSString *str2 = [[NSString alloc] initWithFormat:[[NSString alloc] initWithFormat:@"456"]];
        int i2= [str2 retainCount]; //1 重新分配内存
    
    

     总结:最好不在在调用方法中套用init,可以使用autorelease.

        NSString *str = [[NSString alloc] initWithFormat:@"123"];
        NSString *str2 = str;
      [str release]; str
    = @"23"; int i = [str retainCount]; //-1, str为 int i2 = [str2 retainCount]; //1, str2为"123"

    总结:NSString* 应该指向是常量区,所以str在再赋值为"23"前是否release,结果都是上面。猜想是因为常量区的内存不会被回收.

    所以非copy属性的NSString* 再被赋值前不需要release,也可以release,赋值后可以调用retain,也可以不调用。

    但是alloc的NSString*一定要记得 release.

    非copy属性的NSString*或者NSMutableString*=赋值是不会调用retain的.

    以下为错误的:

        NSMutableString *str = [[NSMutableString alloc] initWithFormat:@"123"];
        NSMutableString *str2 = str;
        int i3 = [str2 retainCount]; //1
        [str release]; //内存被释放了
        str = @"23";
        int i = [str retainCount]; //-1 str为"23"
        int i2 = [str2 retainCount]; //1 str2为nil, 为什么此处str2不为0,猜想是因为 str2不为nil,指针仍指仍指向某块内存,retainCount计算的是指针指向对象的拥有者的个数.

    总结:NSMutableString* 应该指向是分配的内存,所以str在再赋值为"23"前release,内存被回收. str2成为野指针了。会很容易出错的,到时会没法回收啊。必须置为nil.

    所以NSMutablesString*在被赋值后需要调用retain,在再赋值前需要release。临时的NSString*或NSMutableString*对象被赋值都不会调用retain.

    正确的应该为

    NSMutableString *str = [[NSMutableString alloc] initWithFormat:@"123"];
        NSMutableString *str2 = str;
        [str2 retain];
        int i3 = [str retainCount];
        [str release];
        str = @"23";
        int i = [str retainCount]; //-1
        int i2 = [str2 retainCount]; //1 str2 为"123"
    
    

     关于retainCount:

        NSMutableString *str = [[NSMutableString alloc] initWithFormat:@"123"];
        NSMutableString *str2 = str;
        [str2 retain];
        int i = [str2 retainCount]; //2
        
        [str release];
        int i2 = [str2 retainCount]; //1
        int i3 = [str retainCount]; //1,因为此时str仍然指向的是"123", "123"的引用个数为1,即str2指向它,疑问:和前面的str2为nil的有点冲突哈
        str = nil;
        int i4 = [str2 retainCount]; //1
        int i5 = [str retainCount]; //0

     关于属性为copy的NSString*和NSMutableString*的赋值

         @property(copy, nonatomic)NSString *str2; //NSSting* copy赋值会retain

      NSString *str = [[NSString alloc] initWithFormat:@"123"];
        self.str2 = str; //对于str NSString, 相当于是retain,共享同一个内存, 如果使用str2 = str,则不会使用copy属性。
        int i2 = [self.str2 retainCount]; //2
        int i = [str retainCount]; //2 
        str = @"567"; 
        i2 = [self.str2 retainCount]; //2 str2为"123",因为str没有release
        i = [str retainCount]; //-1 str为"567"

     如果str在再赋值前[str release];则:

         @property(copy, nonatomic)NSString *str2; //NSSting* copy赋值会retain
    
      NSString *str = [[NSString alloc] initWithFormat:@"123"];
        self.str2 = str; //对于str NSString, 相当于是retain,共享同一个内存
        int i2 = [self.str2 retainCount]; //2
        int i = [str retainCount]; //2 
        [str release];
        str = @"567"; 
        i2 = [self.str2 retainCount]; //1 str2为"123"
        i = [str retainCount]; //1 str为"567"
      @property(copy, nonatomic)NSMutableString *str2;

    NSMutableString *str = [[NSMutableString alloc] initWithFormat:@"123"]; self.str2 = str; //对于NSMutableString,会重新分配内存,copy为不可变副本 NSMutableString *str3 = str2; int i2 = [self.str2 retainCount]; //1 int i = [str retainCount]; //1 self.str2 = @"567"; i = [str retainCount]; //1 i2 = [self.str2 retainCount]; //-1 int i3 = [str3 retainCount]; //1 说明str2分配的内存并没有释放

    以上总结都是废话,以下为最后的总结:

    1. 千万不在在调用方法中套用init

    2. alloc一定要 release,再赋值

    3. 默认的 NSString*或NSMutableString*是assign属性的,assign赋值不会调用retain.

    4. copy对于NSString*来说是retain计数+1,对于NSMutableString*来说是alloc,都要release 再赋值,如果你不想被其它指针修改指向的内存就用这个吧。

    5. =赋值是不会自动调用release的. 

    6. 最好使用retain属性,否则如果内存被释放掉,你就成了野指针的。

    7. release后,请设为nil.

     

    xcode中的ARC机制的strong就是替代了retain和release动作.

    ARC中的weak替代了assign和设为nil操作,如果内存被释放掉了,会自动将weak的对象置为nil,不会出现野指针的错误。

    所以如果你不想在当前指针操作内存的这段时间内内存被释放掉,请一定要在赋值时使用retain和release,或者copy。

    如果你的目的是在这块内存的生命周期内,暂时的操作这块内存,当前指针的生命周期一定会小于内存的生命周期,可以使用assign.

        NSMutableString *str = [[NSMutableString alloc] initWithString:@"123"];
        int i = [str retainCount];//1
        
        NSArray *array = [[NSArray alloc] initWithObjects:str, nil];
        int i2 = [str retainCount];//2 addObject也会执行retain动作
        [array release];
        
        int i3 = [str retainCount];//1 array release的同时,元素也会执行release动作
  • 相关阅读:
    软件开发规范
    内置模块
    自定义模块
    装饰器 递归
    内置函数 闭包
    生成器 推导式
    函数名运用 新版格式化输出 迭代器
    函数进阶
    pycharm快捷键
    移动端必测点
  • 原文地址:https://www.cnblogs.com/zengyou/p/2628282.html
Copyright © 2020-2023  润新知