289

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

这是我的代码:.h

@interface ViewController : UIViewController {
     NSString *newTitle;
}
@property (strong, nonatomic) NSString *newTitle;

.m

@synthesize newTitle;

有谁知道我该如何解决这个问题?谢谢!!

4

10 回答 10

619

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

如果您使用名称以“alloc”、“new”、“copy”或“mutableCopy”开头的方法创建对象,则您拥有该对象的所有权。

一个名为 的属性newTitle在合成时会产生一个名为 的方法-newTitle,因此会产生警告/错误。-newTitle应该是newTitle属性的 getter 方法,但是命名约定规定名称以开头的方法new返回调用者拥有的对象,这不是 getter 方法的情况。

您可以通过以下方式解决此问题:

  1. 重命名该属性:

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

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
    
  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
    

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


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

您不能为属性指定以newor开头的名称copy

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


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

于 2011-06-13T07:11:54.187 回答
57

不可接受的对象名称

  • 新按钮
  • 复制标签
  • 分配标题

可接受的对象名称

  • 纽扣
  • mCopyLabel
  • _allocTitle

#arc #auto-synthesized #xcode-4.6.1

** 编辑 **

显然你也不能使用mutableCopy

于 2013-04-23T18:24:56.433 回答
31

The name of the member starting with new is what triggers the warning. Change the name to editedTitle and the warning will go away. I was unable to find documentation confirming this but through testing was able to determine that member variables that begin with 'new' aggravate the compiler.

于 2011-10-10T12:11:44.440 回答
10

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

@property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;
于 2013-05-09T01:08:31.683 回答
6

看起来 Bavarious 所建议的并不是你想要做的。您要做的就是声明一个实例变量NewTitle,然后合成属性。我们过去必须声明实例变量和属性。不再。

现在,我相信这样做的正确方法如下:

。H

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

@synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage

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

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

于 2011-08-09T19:44:47.627 回答
4

在 CoreData 中,如果您在属性中使用“new...”(正常编译),它将随机崩溃并出现“错误访问”异常。

没有崩溃日志,显示“所有异常断点”的行根本不会帮助您。

于 2013-11-07T10:52:28.303 回答
3

手动编写一个名称与属性相同的设置器已删除此警告。

于 2012-02-07T18:03:19.200 回答
1

除了您应该/不能在属性名称前使用“新”的问题之外,让我们再说一件事:尽量避免在一般名称前使用“新”。“新”取决于时间。目前它对你来说是新的,但一段时间后你可能想再次实现一些新的东西。所以在名字中使用“新”总是不好的。试着这样想:在编程世界中,“新”总是在创造一些东西:一个东西的新实例。

在您的情况下,当您想要分配不同的标题时,您的属性 titleReplacement 的当前名称。

还有一件事:尝试先用动词命名函数和方法,例如 setSomething 或 getSomething。但是在属性中尝试首先命名对象,例如 heightMinimum、heightMaximum 等 -> 当您在编码时使用检查器时,您总是在寻找对象。试试看。;-)

于 2014-08-03T20:29:35.820 回答
1

NS_RETURNS_NOT_RETAINED用于解决命名问题。

@property (nonatomic, copy) NSString *newTitle NS_RETURNS_NOT_RETAINED;

我们可以找到它的定义如下,

#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))

“ns_returns_not_retained”属性是“ns_returns_retained”的补充。如果一个函数或方法可能看起来遵守 Cocoa 约定并返回一个保留的 Cocoa 对象,则此属性可用于指示返回的对象引用不应被视为返回给调用者的“拥有”引用。Foundation 框架定义了一个宏 NS_RETURNS_NOT_RETAINED,它在功能上等同于下面显示的宏。

在此处附上更多详细信息

于 2018-08-01T01:12:34.210 回答
-2

尝试这个:-

@property (nonatomic,retain) NSString *newTitle;
于 2011-06-13T07:03:01.883 回答