我目前正在使用iOS 5 SDK尝试开发我的应用。 我正在尝试将NSString作为一个属性,然后在.m文件中合成它(之前我已经完成了这个,没有任何问题)。现在,我遇到了这个问题:“语义问题:属性的合成getter遵循Cocoa命名约定来返回'拥有'对象。”
这是我的代码: .H
@interface ViewController : UIViewController {
NSString *newTitle;
}
@property (strong, nonatomic) NSString *newTitle;
的.m
@synthesize newTitle;
有没有人知道如何解决这个问题? 谢谢!
答案 0 :(得分:601)
我的猜测是你正在使用的编译器版本跟the memory management rules一样用于声明的属性 - 更具体地说,对于声明的属性的访问者:
如果使用名称以“alloc”,“new”,“copy”或“mutableCopy”开头的方法创建对象,则获取对象的所有权。
名为newTitle
的属性在合成时会生成一个名为-newTitle
的方法,因此会出现警告/错误。 -newTitle
应该是newTitle
属性的getter方法,但是命名约定声明名称以new
开头的方法返回一个由调用者拥有的对象,而不是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
请注意,即使此解决方案允许您将newTitle
保留为属性名称和getter名称,但是如果方法名为-newTitle
且不返回调用方拥有的对象,则可以让阅读代码的其他人感到困惑。
为了记录,Apple发布了Transitioning to ARC Release Notes,其中声明:
您无法为商家提供以
new
或copy
开头的名称。
他们已经被告知他们的陈述不太准确:罪魁祸首是getter方法名称,而不是属性名称。
编辑2015年1月17日:我刚刚注意到recent commit to Clang建议使用上面的选项3(使用objc_method_family(none)
),包括修复它,一般情况其中属性名称与特殊方法系列前缀之一匹配。 Xcode最终可能会纳入这一变化。
答案 1 :(得分:50)
#arc#自动合成#xcode-4.6.1
**编辑**
显然你不能使用 mutableCopy 。
答案 2 :(得分:29)
以new开头的成员名称是触发警告的原因。将名称更改为editedTitle,警告将消失。我无法找到确认这一点的文档,但通过测试能够确定以'new'开头的成员变量会加剧编译器。
答案 3 :(得分:7)
ARC不允许在属性名称中使用“New ....”。但您可以通过更改getter名称来使用“newTitle”。
@property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;
答案 4 :(得分:5)
看起来巴伐利亚的建议并不像你想要做的那样。您要做的只是声明一个实例变量NewTitle
,然后合成该属性。我们以前必须声明实例变量和属性。没有了。
现在,我认为正确的做法如下:
·H
@interface ViewController : UIViewController
@property (nonatomic, strong) NSString *newTitle;
的.m
@synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage
合成属性newTitle
的实例变量。您不希望实例变量与您的属性相同 - too easy to make mistakes。
答案 5 :(得分:3)
在CoreData中,如果在属性中使用“new ...”(正常编译),它将随机崩溃并出现“错误访问”异常。
没有崩溃日志,显示“All Exceptions Breakpoint”的行根本无法帮助您。
答案 6 :(得分:2)
手动编写一个setter,其名称与该属性相同,删除了此警告。
答案 7 :(得分:0)
除了你应该/不能在你的属性名称前使用“new”的问题之外,再说一点:尽量避免在名字前面使用“new”。 “新”取决于时间。目前它对你来说是新的,但是一段时间之后你可能想要再次实现新的东西。所以在名字中使用“new”总是很糟糕。试着这样思考:在编程世界中,“新”总是在创造一些东西:一个新的事物实例。
在您要分配不同标题的情况下,当前名称为您的属性titleReplacement。
还有一件事:尝试先用动词命名函数和方法,比如setSomething或getSomething。 但是在属性中首先尝试命名对象,如heightMinimum,heightMaximum等。 - >当您在编码时使用检查器时,您总是在寻找物体。试试看。 ; - )
答案 8 :(得分:0)
NS_RETURNS_NOT_RETAINED
用于解决命名问题。
@property (nonatomic, copy) NSString *newTitle NS_RETURNS_NOT_RETAINED;
我们可以如下找到其definition,
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
“ ns_returns_not_retained”属性是“ ns_returns_retained”的补充。如果函数或方法似乎遵循Cocoa约定并返回保留的Cocoa对象,则此属性可用于指示返回的对象引用不应被视为返回给调用方的“拥有”引用。 Foundation框架定义了一个宏NS_RETURNS_NOT_RETAINED,该宏在功能上等效于下面显示的宏。
在此处附加more details。
答案 9 :(得分:-2)
试试这个: -
@property (nonatomic,retain) NSString *newTitle;