Objective-C中赋值属性的方法之间的差异

时间:2011-12-30 03:13:11

标签: objective-c

以下是在Objective-C中分配属性的两种方法:

方法1

// in header
@interface Book : NSObject {
    NSString *_title;
}

@property (nonatomic, retain) NSString *title;

// in implementation
@implementation Book
@synthesize title = _title;

方法2

// in header
@interface Book : NSObject {
    NSString *title;
}

@property (nonatomic, retain) NSString *title;

// in implementation
@implementation Book
@synthesize title;

有什么区别?我最近使用方法1,因为更多教程推荐方法1,但没有人解释原因。

2 个答案:

答案 0 :(得分:6)

不同之处在于名称。在#2中,属性和实例字段具有相同的名称。在#1中他们有不同的名字。

#1的优点是,当您表示实例字段时,很难意外引用该属性,反之亦然。引用错误的对象可能会导致对象保留两次或根本不保留。

#2的优势在于它稍微简单一点,如果你在使用时小心谨慎并且有点正式,它就能正常工作。

[而且,我看到,一种口味指定assign而另一种retain,这是一个完全不同的讲座。您通常不会将assign与对象指针一起使用。]

答案 1 :(得分:0)

首先,我建议您对copy类型的实例使用retain而不是assign(和NSString)。如果它是Mutable,那么它会被复制;如果没有,那么它就会被保留 也许你会喜欢THIS DISCUSSION


对于你的问题,区别在于第一个使用相同的名称,第二个使用iVar&的不同名称。 property
实际上,您有一个方法3可供使用:

// in header
@interface Book : NSObject {
}

@property (nonatomic, copy) NSString *title;

// in implementation
@implementation Book
@synthesize title;
  

要使@synthesize在遗留运行时中工作,您必须提供具有相同名称和属性的兼容类型的实例变量,或者在@synthesize语句中指定另一个现有实例变量。对于现代运行时,如果您不提供实例变量,编译器会为您添加一个。例如,给定以下类声明和实现。

以下是官方文档的示例代码,您可以明确说明(它包括 METHOD 1 & METHOD 2 之间的差异):

@interface MyClass : NSObject {
    float sameName;
    float otherName;
}
@property float sameName;
@property float differentName;
@property float noDeclaredIvar;
@end

@implementation MyClass
@synthesize sameName;
@synthesize differentName=otherName;
@synthesize noDeclaredIvar;
@end

旧版运行时的编译器会在@synthesize noDeclaredIvar;生成错误,而现代运行时的编译器会添加一个实例变量来表示{{1 }}。

  

注意:Mac OS X v10.5及更高版本上的iPhone应用程序和64位程序使用现代版本的运行时。其他程序(Mac OS X桌面上的32位程序)使用运行时的旧版本。你可以参考HERE)。

但是,我建议使用 METHOD 1 METHOD 3 。由于您可以在代码中使用noDeclaredIvar,因此该属性可以帮助您管理self.title& alloc。如果你使用 METHOD 2 ,你可以将releasetitle混合(但self.title更清楚,呃?)。 :)