objective-c - 我们是否必须保留非 ARC 中方法返回的对象?

标签 objective-c automatic-ref-counting release retain

考虑在手动保留释放中实现的情况,其中我有一个变量指向方法返回的对象。

{
    ...
    NSString *str = [self myNewString];
    ...
}

- (NSString *)myNewString
{
    NSString *myString = [NSString stringWithFormat:@"%d-String", 1];
    return myString;
}

这里我们是否必须保留myNewString返回的对象,以便我们在使用它时不会释放它?

请帮助我,我是 Objective-C 新手。提前致谢。

最佳答案

这个答案有两个方面:

  1. 首先,您要遵守方法命名规则,该规则规定名称以“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];
    }
    
  2. 因此,如果调用者想要确保保留该对象,它可以只调用返回 +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/

相关文章:

Objective-C "if"语句不保留

objective-c - NSString 的 isLike : actually do? 是什么意思

ios - 在 ARC 下将委托(delegate)设置为 nil?

java - 强制 Maven 清理

asp.net - 编译调试 ="false"和 Release模式有什么区别?

iphone - 将唯一标识符从 IOS 设备发送到 Web 服务

ios - [UIBarItem setTitle :]: unrecognized selector sent to instance

objective-c - 在 Objective-C 中声明我类的代表持有的对象的所有权

ios - 弹回 View Controller 时使用 ARC 的 EXC_BAD_ACCESS

android - 已签名的 APK 在使用 back4app 时与 Android Studio 构建的行为不同,并在 google play 上发布。如何解决?