【问题标题】:why lowercaseString of NSString is not released after the original NSString object is released?为什么原始NSString对象释放后NSString的小写字符串没有释放?
【发布时间】:2014-10-18 09:43:32
【问题描述】:

请检查以下代码:

CFUUIDRef uuid=CFUUIDCreate(kCFAllocatorDefault);
NSString *strUuid=(NSString *)CFUUIDCreateString(kCFAllocatorDefault,uuid);
NSString *lowerUuid=[strUuid lowercaseString];
NSLog(@"strUuid retainCount:%tu",[strUuid retainCount]);
CFRelease(strUuid);
CFRelease(uuid);
NSLog(@"lowerUuid retainCount:%tu",[lowerUuid retainCount]);
NSLog(@"lowerUuid:%@",lowerUuid);

在非 arc 项目中运行此代码,输出将是:

strUuid retainCount:1
lowerUuid retainCount:1
lowerUuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

lowercaseString是NSString的一个属性,它的定义是:

@property (readonly, copy) NSString *lowercaseString;

所以可以合理地推断,如果原始的 NSString 对象被释放,那么 lowercaseString 属性就会在 NSString 的 dealloc 方法中被释放。 但是为什么在上面的代码中,即使释放了原始的strUuid,lowerUuid仍然存在?

【问题讨论】:

  • 我不认为这是一个合理的推论。 copy 属性可能意味着返回的值是原始字符串的副本,并带有它自己的保留计数。

标签: objective-c nsstring


【解决方案1】:

首先,标准免责声明:不要看-retainCount。它的使用有很多注意事项,并且对于任何有用的东西都不能真正被信任。

也就是说:您的推论并未描述正在发生的事情。当您向strUuid 询问-lowercaseString 时,您不会得到某种“子”对象。生成的小写字符串是一个完全独立的对象,具有自己的内部保留计数。 (可能原始字符串确实保留了自己对小写字符串的引用,但这不是您关心的问题。)

在您的代码 sn-p 中,根据标准内存管理约定,一般情况下发生的情况是语句 [strUuid lowercaseString] 返回一个“自动释放”对象。这样即使原始字符串被释放,返回给您的字符串仍然有效:(a)至少直到自动释放池被清理或(b)在其最后一次实际访问之后,取决于项目的 ARC 状态。

【讨论】:

  • 好答案。稍微扩展一下:仅仅因为某物被声明为@property 并不意味着它是某种从属对象。只读属性只是一个 getter 方法,可以返回其实现者想要的任何东西。
  • 某事物被声明为@property 并不意味着它是某种从属对象!这就是让我感到困惑的一点,我曾经认为属性必须是从属对象。谢谢!
猜你喜欢
  • 2011-08-22
  • 1970-01-01
  • 2011-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多