考虑在手动保留释放中实现的情况,其中我有一个变量指向方法返回的对象。
{
...
NSString *str = [self myNewString];
...
}
- (NSString *)myNewString
{
NSString *myString = [NSString stringWithFormat:@"%d-String", 1];
return myString;
}
这里我们是否必须保留myNewString
返回的对象,以便我们在使用它时不会释放它?
请帮助我,我是 Objective-C 新手。提前致谢。
最佳答案
这个答案有两个方面:
首先,您要遵守方法命名规则,该规则规定名称以“alloc”、“new”、“copy”或“mutableCopy”开头的任何方法都应具有 +1 保留计数(即所有权已转移),否则应该是
autorelease
对象(或者更准确地说,所有权未转移的任何对象,如果调用者想要声明所有权,则必须手动retain
它)。顺便说一句,ARC使用这些方法名称前缀来自动确定对象内存语义,但在手动保留和释放(MRR)代码中,确保方法的内存管理符合方法名称隐含的语义。如果您在将来某个时候将此 MRR 代码与 ARC 代码集成,遵循此方法命名规则将变得很重要。如果您的旧代码违反了此方法命名约定,则可以使用代码提示,但最好确保代码的内存语义符合此方法命名规则。
无论如何,此方法命名规则包含在 Basic Memory Management Rules 中高级内存管理编程指南中概述。
因此,在手动保留和释放时,您有两种选择之一。如果该方法以“alloc”、“new”、“copy”或“mutableCopy”开头,那么它应该通过返回 +1
retainCount
来转移所有权。对象,例如:- (NSString *)newSomeString { return [[NSString alloc] initWithFormat:@"%d-String", 1]; }
否则,它不应该转移所有权(例如返回
autorelease
对象),例如:- (NSString *)someString { return [NSString stringWithFormat:@"%d-String", 1]; }
因此,如果调用者想要确保保留该对象,它可以只调用返回 +1 对象的方法:
NSString *string = [self newSomeString];
或者,调用返回
autorelease
的版本对象,但随后明确retain
它:NSString *string = [[self someString] retain];
实际上,后一个约定,someString
例如,更常见(使用返回 autorelease
对象的方法,即方法名称不以“alloc”、“new”、“copy”或“mutableCopy”开头;然后如果调用者需要 retain
它,它应该明确地这样做)。 new
, copy
,和mutableCopy
所有方法通常都在各自非常特定的上下文中使用,这不适用于此处。
顺便说一句,如果您通过静态分析器(Xcode 的“产品”菜单上的“分析”)运行代码,如果您的 MRR 代码存在过度保留对象或未能保留对象的问题,它会非常好的向您发出警告他们。
但最重要的是,请仔细遵循basic memory management rules ,包括命名方法的约定,然后如果需要保留它,请显式 retain
你的autorelease
对象或调用返回 +1 retainCount
的方法对象。
关于objective-c - 我们是否必须保留非 ARC 中方法返回的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20779709/