0

在这里,我以十种不同的方式分配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上面提到的分配的保留计数是多少?我怎么知道它们的保留计数对于所有这些保留计数都不同?

4

2 回答 2

4

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

特别注意事项

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

于 2013-04-19T02:50:30.917 回答
4

我假设它们是在一些 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。

只记得:

  1. 不要依赖retainCount,
  2. 当你通过 alloc、new、copy、mutable 拷贝创建对象时——释放它是你的责任。如果您使用 [NSString string] 之类的对象创建对象,它将被自动释放。
  3. 保留属性保留对象,复制属性复制对象,属性通常通过点表示法(self.property 等)使用(还有 set%Property% 和 %property% 方法合成,所以 self.property = ... (通常)与 [self setProperty:...] 相同)
  4. 是时候转移到 ARC 了。因此,如果可以的话,您应该这样做。
于 2013-04-19T02:50:43.800 回答