Objective c 使用NSString对象管理内存
以下是我的主要方法:Objective c 使用NSString对象管理内存,objective-c,cocoa,Objective C,Cocoa,以下是我的主要方法: int main (int argc, const char * argv[]) { NSString *string=[[NSString alloc]init]; NSLog(@"%@ The retain count is:%d", string, [string retainCount]); NSLog(@"Hello, World!"); return 0; } 执行这段代码时的输出是“保留计数为:
int main (int argc, const char * argv[]) {
NSString *string=[[NSString alloc]init];
NSLog(@"%@ The retain count is:%d", string, [string retainCount]);
NSLog(@"Hello, World!");
return 0;
}
执行这段代码时的输出是“保留计数为:-1”。我希望它给我1作为保留计数,因为我使用alloc创建了对象。 我在尝试保留或释放NSString对象时也遇到类似的问题 当我尝试使用NSArray时,我在创建对象后立即获得保留计数为2。我不明白如何处理这些物体的机理。 请解释!
提前感谢。-1是将
UINT_MAX
强制转换为有符号值时得到的值UINT_MAX
是记录在案的从未发布的对象的保留计数,包括字符串文字对象
说到保留计数,我建议阅读关于如何保留计数通常没有用处的大方框。您不应该关注原始的保留计数值,因为根据不同的情况,这可能是不同的值。例如,在第一行中,您正在分配与
@“
”等价的内容,即空字符串。这是由一个无法解除分配的对象优化的,并且在您“分配”它的任何地方共享。所有静态字符串也是如此,例如查看[@“Hello”retainCount]
返回的值
相反,您应该关注相对保留计数。也就是说,保留计数是增加了(+1
),还是保持不变(+0
),还是减少了(-1
)。您始终需要确保这些相对值的总和为0
例如:
Foo *foo = [[Foo alloc] init];
[foo retain];
[foo release];
[foo autorelease];
alloc
方法返回带有+1
的对象,retain
也将计数增加1。因此,在第2行的末尾,我们处于+2
。release
和autorelease
都具有-1
的效果,因此在第4行的末尾,您处于+0
,一切正常
有几个简单的规则:如果方法名称是alloc
,以单词copy
或create
开头,那么您将得到一个具有retain count+1
的对象。所有其他方法(尤其是以get
开头的方法)都应该返回retaincount+0
的对象。如果您的方法需要创建对象,但其名称暗示应返回+0
对象,则可以执行以下操作:
- (Foo *) bar {
Foo *result = [[Foo alloc] init]; // +1
return [result autorelease]; // -1
// Object lives until the autorelease pool is drained,
// but relative retain count is +0.
}
永远不要看计数。它几乎毫无用处,只会引起混乱@DarkDust对于如何管理内存有一个很好的答案。int main(int argc,const char*argv[]){NSString*string=[[NSString alloc]init];NSLog(@“%@保留计数为:%d”,string,[string retainCount]);NSLog(@“Hello,World!”);返回0;}这就是为什么您不应该真正查看相对保留计数的原因。自动释放不影响保留计数。它所做的是将所有权转移到自动释放池。
create
并不意味着在Cocoa land中“返回拥有的引用”。这意味着在CF土地上;在Cocoa中,单词是new
。(记住缩写词NARC:New、Alloc、Retain或Copy。)另外,强制链接:@JeremyP:You关于转移所有权是正确的,但是如果您将自动释放
发送到一个对象x次,池稍后将对该对象x次调用释放
。为了让你的记忆保持干净,你确实需要关心相对保留计数,或者你如何确保对象在正确的时间得到清理(并且确实得到清理)?@Peter Hosey:你说得对,感谢你的澄清和强制性链接:-)@Sahitya Tarumani:你分配的所有东西都必须取消分配。在可可中,你不会直接这样做;相反,您释放了对象,当拥有对象的所有东西都释放了对象时,它就会释放自己。从未分配过的对象(如文字字符串)不需要取消分配;由于确保仅在适当的时间解除分配是引用计数的唯一原因,因此不会自行解除分配的对象不需要计数。这样的对象返回UINT\u MAX
作为其保留计数。这些是我在另一条评论中所说的“永久对象”。“一个从未分配过的对象,例如文字字符串”…我确实使用了语句{…NSString*string=[[NSString alloc]init];…}…这个语句没有为字符串分配内存吗?哎呀!没有引起足够的注意[[NSString alloc]init]
不是字符串文字,但它为您提供了一个单例,即永久的空字符串对象。(它不需要每次都创建一个新对象,因为NSStrings是不可变的。)@Sahitya Tarumani:正如Ahruman所说,在当前的实现中不需要创建新对象,这就是不遵守规则的方法。但是,这可能会发生,所以你无论如何都应该遵守规则。@Sahitya Tarumani:没关系。不要担心对象是否是永久的。这是琐事,而不是任何会影响你如何编写代码的事情。它也可能随时发生变化。只需始终遵循文档中描述的规则即可。