语义问题:属性的合成getter遵循Cocoa命名约定来返回'拥有'对象

Noa*_*oam 282 variables properties objective-c ios5 automatic-ref-counting

我目前正在使用iOS 5 SDK试图开发我的应用程序.我正在尝试将NSString作为一个属性,然后在.m文件中合成它(之前我已经完成了这个,没有任何问题).现在,我遇到了这个问题:"语义问题:属性的合成getter遵循Cocoa命名约定来返回'拥有'对象."

这是我的代码:.h

@interface ViewController : UIViewController {
     NSString *newTitle;
}
@property (strong, nonatomic) NSString *newTitle;
Run Code Online (Sandbox Code Playgroud)

.M

@synthesize newTitle;
Run Code Online (Sandbox Code Playgroud)

有没有人知道如何解决这个问题?谢谢!!

小智 606

我的猜测是你正在使用的编译器版本也遵循声明属性的内存管理规则 - 更具体地说,对于声明的属性的访问器:

如果使用名称以"alloc","new","copy"或"mutableCopy"开头的方法创建对象,则可以获取对象的所有权.

newTitle合成时命名的属性会生成一个被调用的方法-newTitle,因此会出现警告/错误.-newTitle应该是newTitle属性的getter方法,但是命名约定声明一个名称以其开头的方法new返回一个由调用者拥有的对象,这不是getter方法的情况.

你可以通过以下方式解决

  1. 重命名该属性:

    @property (strong, nonatomic) NSString *theNewTitle;
    
    Run Code Online (Sandbox Code Playgroud)
  2. 保留属性名称并指定不以特殊方法名称前缀之一开头的getter名称:

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 同时保留属性名称和getter名称,并告诉编译器,即使getter名称以逗号开头new,它也属于none方法系列而不是new方法系列:

    #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) NSString *newTitle;
    - (NSString *)newTitle BV_OBJC_METHOD_FAMILY_NONE;
    @end
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,即使此解决方案允许您同时保留newTitle属性名称和getter名称,但是如果调用的方法-newTitle不返回调用方拥有的对象,则可能会让其他人阅读您的代码时感到困惑.


为了记录,Apple发布了Transitioning to ARC Release Notes,其中声明:

您不能为属性指定以new或开头的名称copy.

他们已经被告知他们的陈述不太准确:罪魁祸首是getter方法名称,而不是属性名称.


编辑2015年1月17日:我刚刚注意到最近对Clang的提交建议上面的选项3(使用objc_method_family(none)),包括修复它,对于属性名称与特殊方法系列前缀之一匹配的一般情况.Xcode最终可能会包含这一变化.

  • 精彩的回答.我的变量以"new"为前缀. (8认同)
  • 像魅力男人一样工作!谢谢!!!供将来参考 - 我使用了"@property(strong,nonatomic,getter = theNewTitle)NSString*newTitle;" (6认同)

Jac*_*nkr 51

不可接受的对象名称

  • newButton
  • copyLabel
  • allocTitle

可接受的对象名称

  • neueButton
  • mCopyLabel
  • _allocTitle

#arc #auto-synthesis#xcode-4.6.1

**编辑**

显然你也不能使用mutableCopy.


小智 30

以new开头的成员的名称是触发警告的原因.将名称更改为editedTitle,警告将消失.我无法找到确认这一点的文档但是通过测试能够确定以'new'开头的成员变量会加剧编译器.


小智 8

ARC不允许在属性名称中使用"New ....".但您可以通过更改getter名称来使用"newTitle".

@property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;
Run Code Online (Sandbox Code Playgroud)


小智 6

它看起来不像Bavarious所暗示的那样是你想要做的.您要做的就是声明一个实例变量NewTitle,然后合成该属性.我们以前必须声明实例变量和属性.不再.

现在,我认为正确的做法如下:

.H

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;
Run Code Online (Sandbox Code Playgroud)

.M

@synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage
Run Code Online (Sandbox Code Playgroud)

newTitle合成属性的实例变量.您不希望实例变量与您的属性相同 - 太容易出错.

请参见示例:声明属性和合成访问器