NSString保留计数

时间:2015-04-10 12:11:10

标签: ios retaincount

在下面提到的代码段中,NSString的保留计数是什么?

self.a = @"abcd"; // self.a is a NSString with (nonatomic, Strong) Attributes

NSLog(@"Retain Count of A == %d",(int)[self.a retainCount]);

self.b = self.a;// self.b is a NSString with (nonatomic, Strong) Attributes

NSLog(@"Retain Count of A == %d",(int)[self.a retainCount]);
NSLog(@"Retain Count of B == %d",(int)[self.b retainCount]);

[self.a release];

NSLog(@"Retain Count of A == %d",(int)[self.a retainCount]);
NSLog(@"Retain Count of B == %d",(int)[self.b retainCount]);


//Similarly whats the retain count if:
self.b = [self.a retain];

1 个答案:

答案 0 :(得分:0)

@"abcd"是一个字符串文字。它存储为常量。如果您要记录[@"abcd" class],那么您将获得__NSCFConstantString(虽然这是一个经验观察;但不保证类名)。 retainrelease等在常量字符串上是无操作的,因为它本身具有与应用程序相同的生命周期。在实践中,正如vikingosegundo所说,你得到NSUIntegerMax

您正在使用属性,因此实际发生的情况取决于您的属性类型。

使用self.b = self.a您期望的是:

  • getter self.a返回[[string retain] autorelease],因此在当前自动释放池的生命周期内,retain count会递增;
  • setter self.b =保留字符串,因此保留计数再次递增,为self字符串所有权的生命周期。

如果你在自动释放池的生命周期内检查一个长期增量,那么两个增量。

retainrelease的手动调用完全符合您的想法。

在ARC下,您不会手动调用任何这些内容,包括retainCount,并且可以优化各种保留和发布。一个着名的案例是,自动释放池中随后保留的内容可以从池中删除。因此,self.b = self.a可能会以保留计数结束只有一个,并且字符串不在自动释放池中,如果优化器感觉像这样。

使用手动引用计数时的规则非常简单:

  • 如果你有一个拥有的引用 - 一个由new,alloc,retain或copy返回 - 然后释放或自动释放引用;
  • 如果你有一个非拥有的参考 - 即任何其他类型,最常见的是,这将来自一个香草的吸气剂 - 然后不要释放参考。但是,不一定要求它在当前自动释放池的生命周期内有效。

return [[a retain] autorelease]模式来自self的生命周期可能短于池的观察结果。