为什么在释放原始NSString对象后不释放NSString的lowercaseString?

时间:2014-10-18 01:25:55

标签: objective-c nsstring

请检查以下代码:

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);

在非弧项目中运行此代码,输出将为:

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

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

@property (readonly, copy) NSString *lowercaseString;

因此推断如果释放原始NSString对象是合理的,则将在NSString的dealloc方法中释放lowercaseString属性。 但是为什么在上面的代码中,即使在最初的strUuid发布之后,lowerUuid仍然存在?

1 个答案:

答案 0 :(得分:3)

首先,标准免责声明:不要看-retainCount。它有许多注意事项,对于任何有用的东西都不可信任。

那说:你的推论没有描述发生了什么。当您向strUuid询问-lowercaseString时,您没有得到某种儿童"宾语。生成的小写字符串是一个完全独立的对象,具有自己的内部保留计数。 (可能原始字符串确实保留了对小写字符串的引用,但这不是您的关注。)

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