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

1
2
3
4
5
// 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. 重命名属性
1
@property (strong, nonatomic)UITextField *theNewPasswordTextField;
  1. 修改getter方法名
1
@property (strong, nonatomic, getter=theNewPasswordTextField) UITextField *newPasswordTextField;
  1. 指明 attribute((objc_method_family(none)))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#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
@property (strong, nonatomic)UITextField *newPasswordTextField;
- (UITextField *)newPasswordTextField BV_OBJC_METHOD_FAMILY_NONE;
@end

参考链接

stackoverflow1⃣️

stackoverflow2⃣️