语义问题:属性的合成getter遵循Cocoa命名惯例,返回'owned'对象

我目前正在使用iOS 5 SDK试图开发我的应用程序。 我试图使一个NSString属性,然后合成它在.m文件(我已经这样做之前没有问题)。现在,我遇到了这样的问题:“语义问题:属性的合成getter遵循Cocoa命名约定,用于返回‘拥有的’对象。”< / p > 这是我的代码: . h < / p >
@interface ViewController : UIViewController {
NSString *newTitle;
}
@property (strong, nonatomic) NSString *newTitle;

00

@synthesize newTitle;
有人知道我该如何解决这个问题吗? 谢谢! !< / p >
80678 次浏览

试试这个:

@property (nonatomic,retain) NSString *newTitle;

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

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

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

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

  1. 重命名属性:

    @property (strong, nonatomic) NSString *theNewTitle;
    
  2. 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;
    
  3. 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
    

    请注意,尽管这个解决方案允许你保留newTitle作为属性名和getter名,但有一个名为-newTitle的方法,它不返回调用者拥有的对象,可能会让阅读你的代码的其他人感到困惑


在记录中,苹果发布了过渡到ARC发行说明,他们在其中声明:

不能给属性以newcopy开头的名称。

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


我刚刚注意到一个最近致力于Clang,它建议上面的选项3(使用objc_method_family(none)),包括一个修复,用于属性名匹配特殊方法族前缀之一的一般情况。Xcode最终可能会包含这个变化。

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

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

. h

@interface ViewController : UIViewController


@property (nonatomic, strong) NSString *newTitle;

00

@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等。->当你在编码时使用检查器时,你总是在寻找对象。试试吧。: -) < / p >

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