【问题标题】:Property name starting with 'new' prefix leads to BAD_ACCESS error in iOS以“new”前缀开头的属性名称导致 iOS 中的 BAD_ACCESS 错误
【发布时间】:2014-06-19 13:45:56
【问题描述】:

我的属性在我的 NSManagedObject 类中声明,名称为“newPrice”,导致“僵尸对象”。经过几个小时的调试,我发现释放此对象但未保留它的方法存在问题。将此属性重命名为“priceNew”后,一切顺利。我不明白为什么这会导致问题。

财产声明:

@property (nonatomic, retain) NSNumber * newPrice;

这个调用导致问题:

[self setPieceStateWithPrice:self.action.newPrice];

在传递了像 self.action.priceNew 这样重命名的参数后,一切顺利......

【问题讨论】:

    标签: ios objective-c cocoa-touch


    【解决方案1】:

    不要那样做。

    在 Objective-C 命名约定中,名称以 new 开头的方法应返回保留对象。使用 ARC,该命名约定成为一项要求。这意味着一个普通的 ARC 编译方法不应该以名称 new 开头,因为编译器会假定它的保留计数已经为 1。

    引用文档:

    您拥有您创建的任何对象

    您使用名称以“alloc”开头的方法创建对象, “new”、“copy”或“mutableCopy”(例如,alloc、newObject 或 可变复制)。

    【讨论】:

    • 很好奇这种约定是否仍然是 Swift 中的最佳实践。从功能上讲,在属性名称前加上 new 在 Swift 中似乎是完全安全的(对保留计数没有影响,编译也没有问题)。有什么想法吗?
    • 如果将变量声明为动态变量,则在 Swift 中不安全!
    • “当从这样的函数或方法返回时,ARC 会在返回语句的评估点保留值,然后再离开所有本地范围”。根据Clang 中所说的,该值应在从newPrice 返回之前保留。因此,它保留计数为 1 的断言应该是正确的。这意味着它实际上不应该被过度发布。
    • 如果我要使用变量“newsId”,会导致问题吗?只是想知道
    【解决方案2】:

    属性具有自动为它们合成的方法。因此,拥有一个属性意味着拥有一个同名的方法。

    alloccopyinitmutableCopynew 开头的方法对它们如何处理内存有特殊的假设。除非您有非常充分的理由,否则您应该避免使用这些前缀。

    来自Clang 3.5 documentation | Objective-C Automatic Reference Counting | Retained return values

    返回可保留对象指针类型的函数或方法可以标记为返回保留值,表示调用者期望获得 +1 保留计数的所有权。

    alloc、copy、init、mutableCopy 和 new 系列中的方法被隐式标记为 attribute((ns_returns_retained))。这可以通过显式标记方法 attribute((ns_returns_not_retained)) 来抑制。

    【讨论】:

    • 我不知道那个编译器开关。感谢分享那个金块。 (当你第一次发布它时投了回去。)看起来这个开关在苹果代码中的使用方式是在方法前面加上NS_RETURNS_RETAINED
    猜你喜欢
    • 2014-02-13
    • 1970-01-01
    • 1970-01-01
    • 2017-12-12
    • 2021-12-06
    • 2018-06-25
    • 2017-04-04
    • 1970-01-01
    • 2011-07-31
    相关资源
    最近更新 更多