Just a little smile ^ ^

yoyo_zeng

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
    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动作

 

 

posted on 2012-08-08 15:01  yoyo_zeng  阅读(373)  评论(0编辑  收藏  举报