下面提到的 NSStrings 分配的保留计数是多少

Posted

技术标签:

【中文标题】下面提到的 NSStrings 分配的保留计数是多少【英文标题】:What are the retain count of NSStrings allocations mentioned below 【发布时间】:2013-04-19 02:26:06 【问题描述】:

在这里,我以十种不同的方式分配了NSString 变量,我想知道所有这些变量的保留计数。

@interface SomeClass : NSObject 
 
   NSString *str1; 
   NSString *str2;
 
@property (nonatomic, retain) NSString* str1;
@property (nonatomic, copy) NSString * str2; 


 - str1 =@"hello";

 - self.str1 = @"hello";

 - str1 = [[NSString alloc]init];

 - self.str4 = [[NSString alloc]init];

 - str1 = [[[NSString alloc]init]autorelease];

 - self.str1 = [[[NSString alloc]init]autorelease];

 - str1 = [[NSString alloc]initWithString:@"hello"];

 - self.str1 = [[NSString alloc]initWithString:@"hello"];

 - str1 = [[[NSString alloc]initWithString:@"hello"]autorelease];

 - self.str1 = [[[NSString alloc]initWithString:@"hello"]autorelease];

上面提到的NSString 分配的保留计数是多少?我如何知道它们的保留计数对于所有这些都不同?

【问题讨论】:

你为什么关心保留计数? retainCount 无论如何都不应该使用 因为这个问题是在一个公司面试的时候问我的..所以想知道答案。 如前所述,保留计数是无用的。真正的问题是 Objective-C 如何处理字符串文字以及谁拥有所有权。 您的回复应该是“由于引用计数的工作方式,不可能知道。碰巧,您是指相对保留计数吗?” 告诉公司改用自动引用计数 【参考方案1】:

虽然这看起来像是一项家庭作业,但您可以在每个字符串上调用 retainCount 以获得实际值的近似值。您绝对不应该将此方法用于生产应用程序中的任何逻辑(请参阅http://whentouseretaincount.com)!文档指出:

特殊注意事项

此方法在调试内存管理问题时没有任何价值。因为任何数量的框架对象可能已经保留了一个对象以保存对它的引用,而同时自动释放池可能在一个对象上保存了任何数量的延迟释放,所以您不太可能从中获得有用的信息方法。

【讨论】:

【参考方案2】:

我假设它们是在一些 SomeClass 方法中访问的。变体:

// replace str1 with str2(copy), retain count will remain the same
str1 = @"hello";
self.str1 = @"hello"
str1 = [[NSString alloc]initWithString:@"hello"];
self.str1 = [[NSString alloc]initWithString:@"hello"];
str1 = [[[NSString alloc]initWithString:@"hello"]autorelease];
self.str1 = [[[NSString alloc]initWithString:@"hello"]autorelease];

在这里你会得到一个巨大的值,比如 UINT_MAX,编译器会优化你的代码(你传递文字值,NSString 是不可变的)并且这些对象将是不可释放的。

self.str1 = [[NSString alloc] initWithFormat:@"a string %d", 5]; // with autorelease or not - the same

这里你最终会得到一个释放计数 = 2,你分配字符串 +1,你分配一个保留属性 +1 = 2。

self.str2 = [[NSString alloc] initWithFormat:@"a string %d", 5]; // with autorelease or not - the same

在这里你会得到一个释放计数 = 1,你分配字符串 +1,你分配一个副本属性,从而创建一个已创建字符串 = 1 的副本。

在所有其他情况下,您最终会得到释放计数 = 1,自动释放不会增加保留计数,它只会在池耗尽时将其减 1。

记住:

    不要依赖retainCount, 当您通过 alloc、new、copy、mutable 复制创建对象时 - 您有责任释放它。如果您使用类似 [NSString string] 创建对象,它将被自动释放。 retain 属性保留对象,复制属性复制对象,属性通常通过点表示法(self.property 等)使用(还合成了 set%Property% 和 %property% 方法,因此 self.property = ... 是(通常)与 [self setProperty:...] 相同) 是时候转移到 ARC。因此,如果可以,您应该这样做。

【讨论】:

感谢您的好回答 +1。但仍在等待完整答案。 我错过了什么?我已经涵盖了所有可能的情况。 前两个的保留计数是多少... str1 = @"hello"; self.str1 = @"你好" @Wish 正如我在回答中所写,像 UINT_MAX 这样的巨大价值。 我建议总是在你对对象负责时释放,如果你不这样做就不要。不要依赖编译器优化,保持代码风格并始终符合约定是一个好习惯。

以上是关于下面提到的 NSStrings 分配的保留计数是多少的主要内容,如果未能解决你的问题,请参考以下文章

tableView:cellForRowAtIndexPath 的保留计数:

自动释放对象递减的保留计数何时减少?

为 plist 数组中的每个项目创建新的 NSStrings

如何增加 NSString 类型变量的保留计数? [复制]

查找保留特定对象的对象

使用公式或函数比较单元格值并在 Excel 中打印计数?