Objective-c中属性名以new开头编译报错

property follows cocoa naming convention for returning ‘owned’ objects

问题

当做一个修改密码的页面的时候,很自然的把新密码的输入框命名为newPasswordTextField,此时编译不通过。错误提示如下:

property follows cocoa naming convention for returning ‘owned’ objects

原因

Transitioning to ARC Release Notes中写道: 

You cannot give an accessor a name that begins with new. This in turn means that you can’t, for example, declare a property whose name begins with new unless you specify a different getter
// Won't work:
@property NSString *newTitle;

// Works:
@property (getter=theNewTitle) NSString *newTitle;  

在MRC时代,有约定如果方法名以alloc、copy、init、mutableCopy和new开头且有返回值时,return 对象时先调用一次retain。ARC时代只是把retain交给编译器去自动添加。所以当属性名以new开头时生成的getter方法会有内存管理的语义冲突。

解决办法

  1. 重命名属性
    @property (strong, nonatomic)UITextField *theNewPasswordTextField;
  2. 修改getter方法名

@property (strong, nonatomic, getter=theNewPasswordTextField) UITextField *newPasswordTextField;

  1. 指明 attribute((objc_method_family(none)))

    #ifndef __has_attribute
    #define __has_attribute(x) 0 // Compatibility with non-clang compilers
    #endif
    
    #if __has_attribute(objc_method_family)
    #define BV_OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
    #else
    #define BV_OBJC_METHOD_FAMILY_NONE
    #endif
    
    @interface ViewController : UIViewController
  2. (UITextField *)newPasswordTextField BV_OBJC_METHOD_FAMILY_NONE;
    @end

本文链接:

https://www.devorz.com/index.php/archives/iOS-Property-Prefix-new.html
1 + 8 =
快来做第一个评论的人吧~