语义问题:属性的合成getter遵循Cocoa命名约定来返回“拥有”的对象
我目前正在使用iOS 5 SDK试图开发我的应用程序。 我试图做一个NSString属性,然后在.m文件中进行综合(我之前完成了这个任务没有问题)。 现在,我遇到了这个问题:“语义问题:属性的合成getter遵循Cocoa命名约定来返回”拥有的“对象。
这是我的代码:.h
@interface ViewController : UIViewController { NSString *newTitle; } @property (strong, nonatomic) NSString *newTitle;
.M
@synthesize newTitle;
有没有人有一个线索,我可以解决这个问题? 谢谢!!
我的猜测是,你使用的编译器版本也遵循声明属性的内存pipe理规则 – 更具体地说,对于声明属性的访问器:
如果您使用名称以“alloc”,“new”,“copy”或“mutableCopy”开头的方法创build对象,则可以取得对象的所有权。
名为newTitle
的属性在合成时产生一个名为-newTitle
的方法,因此是警告/错误。 -newTitle
应该是newTitle
属性的getter方法,但是命名约定规定,名称以new
开头的方法返callback用者拥有的对象,这不是getter方法的情况。
你可以通过以下方法解决
-
重命名该属性:
@property (strong, nonatomic) NSString *theNewTitle;
-
保留属性名称并指定一个不以特殊方法名称前缀之一开头的getter名称:
@property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
-
同时保留属性名称和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
请注意,尽pipe此解决scheme允许您将
newTitle
同时保留为属性名称和getter名称,但如果使用名为-newTitle
的方法不返callback用方拥有的对象,则可能会让其他人阅读您的代码时感到困惑。
为了logging,苹果公司已经发布了过渡到ARC版本说明 ,其中他们指出:
你不能给一个属性开始
new
或copy
的名称。
他们已经被通知他们的陈述不太准确:罪魁祸首是getter方法名称,而不是属性名称。
编辑2015年1月17日:我刚刚注意到最近提交给Clang ,build议上面的选项3(使用objc_method_family(none)
),包括修复它,一般情况下属性名称匹配的特殊方法家庭前缀之一。 Xcode最终可能会纳入这一变化。
不可接受的对象名称
- newButton
- copyLabel
- allocTitle
可接受的对象名称
- neueButton
- mCopyLabel
- _allocTitle
#arc#自动合成#xcode-4.6.1
**编辑**
显然你也不能使用mutableCopy 。
以new开始的成员的名称是触发警告的名称。 将名称更改为editedTitle,警告将消失。 我无法find确认这一点的文档,但通过testing可以确定以“新”开头的成员variables会加剧编译器。
ARC不允许在属性名称中使用“New ….”。 但你可以通过改变getter的名字来使用“newTitle”。
@property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;
它看起来不像Bavarious所暗示的那样是你想要做的。 所有你想要做的是声明一个实例variablesNewTitle
然后综合属性。 我们曾经不得不声明实例variables和属性。 不再。
现在,我相信这样做的正确方法如下:
。H
@interface ViewController : UIViewController @property (nonatomic, strong) NSString *newTitle;
.M
@synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage
属性newTitle
的实例variables是合成的。 你不希望你的实例variables和你的属性一样 – 容易犯错误 。
请参阅示例:声明属性和合成访问器
在CoreData中,如果在属性中使用“new …”(通常编译),它将随着“不良访问”exception而随机崩溃。
没有崩溃日志,显示“所有exception断点”的行不会对您有所帮助。
手动使用与属性相同的名称来手动编写setter,即可删除此警告。
除了你应该/不能在你的属性名称前面使用“new”这个问题之外,还要说一件事情:尽量避免名字前面的“new”。 “新”取决于时间。 目前它对你来说是新的,但是一段时间后你可能想要再次实现新的东西。 所以在名称中使用“新”总是不好的。 试着这样思考:在编程的世界里,“新”总是创造出一些东西:一个新的事物。
在你的情况下,当你想分配一个不同的标题,那么当前名称您的财产titleReplacement。
还有一件事:首先尝试给动词命名函数和方法,比如setSomething或者getSomething。 但是在属性中,先尝试命名对象,比如heightMinimum,heightMaximum等。 – >当你使用你的检查器的时候,你总是在寻找对象。 试试看。 😉
尝试这个:-
@property (nonatomic,retain) NSString *newTitle;