提问



我目前正在使用iOS 5 SDK试图开发我的应用程序。
我试图让NSString成为一个属性,然后在.m文件中合成它(之前我没有遇到任何问题)。现在,我遇到了这个:语义问题:属性的合成getter跟随Cocoa返回拥有对象的命名约定。


这是我的代码:
。H


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


.M


@synthesize newTitle;


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

最佳参考


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



  如果使用名称以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,其中声明:[26]



  您不能为属性指定以newcopy开头的名称。



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





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

其它参考1


不可接受的对象名称




  • newButton

  • copyLabel

  • allocTitle



可接受的对象名称




  • neueButton

  • mCopyLabel

  • _allocTitle



#arc #auto-synthesis#xcode-4.6.1


**编辑**


显然你也不能使用 mutableCopy

其它参考2


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

其它参考3


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


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

其它参考4


它看起来并不像Bavarious所说的那样你想做什么。你要做的就是声明一个实例变量NewTitle,然后合成属性。我们以前必须声明实例变量和属性。不再。


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


。H


@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;


.M


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


合成属性newTitle的实例变量。你不希望你的实例变量与你的财产相同 - 太容易犯错误。[28]


请参见示例:声明属性和合成访问器[29]

其它参考5


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


没有崩溃日志,显示All Exceptions Breakpoint的行根本无法帮助您。

其它参考6


手动编写一个setter,其名称与删除此警告的属性相同。

其它参考7


除了你应该/不能在你的房产名称前面使用新的问题之外,再说一件事:尽量避免在名字前面使用新。新取决于时间。目前它对你来说是新的,但是过了一段时间你可能想要再次实现一些新东西。所以在名字中使用new总是很糟糕的。试着这样想:在编程世界中,new总是在创造一些东西:一个新的某事的例子。


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


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

其它参考8


尝试这个:-


@property (nonatomic,retain) NSString *newTitle;