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

这是我的代码: . h

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

.m

@synthesize newTitle;

有人知道我该怎么补救吗? 谢谢! !


试试这个:

@property (nonatomic,retain) NSString *newTitle;

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

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

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

你可以通过以下方法解决:

Renaming that property: @property (strong, nonatomic) NSString *theNewTitle; Keeping the property name and specifying a getter name that doesn’t begin with one of the special method name prefixes: @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle; Keeping both the property name and the getter name, and telling the compiler that, even though the getter name starts with new, it belongs to the none method family as opposed to the new method family: #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 Note that even though this solution allows you to keep newTitle as both the property name and the getter name, having a method called -newTitle that doesn’t return an object owned by the caller can be confusing for other people reading your code.


为了记录,苹果已经发布了过渡到ARC的发布说明,其中他们说:

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

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


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


看起来巴伐利亚的建议并不是你想做的。你所要做的就是声明一个实例变量NewTitle,然后合成属性。我们过去必须声明实例变量和属性。没有更多的。

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

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

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

属性newTitle的实例变量是合成的。你不希望你的实例变量和你的属性一样——太容易出错了。

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


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


手动编写与属性名称相同的setter可以消除此警告。


不可接受的对象名称

newButton copyLabel allocTitle

可接受对象名称

neueButton mCopyLabel _allocTitle

#arc #auto- synthetic #xcode-4.6.1

**编辑**

显然你也不能使用mutableCopy。


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

@property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;

在CoreData中,如果你在属性中使用“new…”(正常编译),它会随机崩溃并出现“坏访问”异常。

没有崩溃日志,并且“所有异常断点”所显示的行对您没有任何帮助。


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

在你的情况下,当你想分配一个不同的标题,那么当前名称你的属性titlreplacement。

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


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,它在功能上与下面所示的宏相同。