关于C#:语义问题:属性的合成getter遵循Cocoa命名约定来返回’拥有’对象

Semantic Issue: Property's synthesized getter follows Cocoa naming convention for returning 'owned' objects

我目前正在使用iOS5sdk来开发我的应用程序。我正在尝试使nsstring成为一个属性,然后在.m文件中合成它(我以前做过,没有问题)。现在,我遇到了这个问题:"语义问题:属性的合成getter遵循cocoa命名约定返回‘owned’对象。"

这是我的代码:h

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

m

1
@synthesize newTitle;

有人知道我怎么解决这个问题吗?谢谢!!


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

You take ownership of an object if you create it using a method whose name begins with"alloc","new","copy", or"mutableCopy".

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

您可以通过以下方式解决此问题:

  • 重命名该属性:

    1
    @property (strong, nonatomic) NSString *theNewTitle;
  • 保留属性名并指定一个不是以某个特殊方法名前缀开头的getter名:

    1
    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
  • 保留属性名和getter名,并告诉编译器,即使getter名以new开头,它还是属于none方法家族,而不是new方法家族:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #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发行说明,其中声明:

    You cannot give a property a name that begins with new or copy.

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

    编辑:2015年1月17日:我刚刚注意到最近一次对clang的承诺,建议使用上面的选项3(使用objc_method_family(none)),包括一个修正它,在一般情况下,属性名与一个特殊方法系列前缀匹配。Xcode最终可能会合并这个变更。


    不可接受的对象名

    • 纽扣
    • 复制标签
    • 分配标题

    可接受的对象名称

    • 纽纽扣
    • 商标标签
    • 第二类标题

    #ARC自动合成Xcode-4.6.1

    **编辑**

    显然你也不能使用可变拷贝。


    以new开头的成员的名称会触发警告。将名称更改为editeditle,警告将消失。我找不到证实这一点的文档,但通过测试可以确定以"new"开头的成员变量会加重编译器的性能。


    arc不允许在属性名中使用"new…."。但是您可以通过更改getter名称来使用"newtitle"。

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


    看起来不像Bavariety建议的是你想做的。您只需要声明一个实例变量newTitle,然后合成该属性。我们以前必须声明实例变量和属性。不再了。

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

    h

    1
    2
    3
    @interface ViewController : UIViewController

    @property (nonatomic, strong) NSString *newTitle;

    m

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

    综合属性newTitle的实例变量。您不希望实例变量与属性相同-太容易出错。

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


    在coredata中,如果在属性(通常编译)中使用"new…",它将随机崩溃,并出现"bad access"异常。

    没有崩溃日志,用"所有异常断点"显示的行对您毫无帮助。


    用与属性相同的名称手动写入setter已删除此警告。


    NS_RETURNS_NOT_RETAINED用于解决命名问题。

    1
    @property (nonatomic, copy) NSString *newTitle NS_RETURNS_NOT_RETAINED;

    我们可以找到它的定义如下:

    1
    #define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))

    The 'ns_returns_not_retained' attribute is the complement of 'ns_returns_retained'. Where a function or method may appear to obey the Cocoa conventions and return a retained Cocoa object, this attribute can be used to indicate that the object reference returned should not be considered as an"owning" reference being returned to the caller. The Foundation framework defines a macro NS_RETURNS_NOT_RETAINED that is functionally equivalent to the one shown below.

    请在此处附加更多详细信息。


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

    在您的情况下,当您希望分配不同的标题时,请指定当前名称,即您的属性标题替换位置。

    还有一件事:尝试先用动词命名函数和方法,比如setsomething或getsomething。但是在属性中,尝试首先命名对象,如heightminimum、heightmaximum等。->当您在编码时使用检查器时,总是在查找对象。试试看。;-)


    试试这个:

    1
    @property (nonatomic,retain) NSString *newTitle;