基本问题是Objective-C属性语法

时间:2010-03-11 16:42:14

标签: objective-c cocoa cocoa-touch

关于Objective C中属性的语法和用法,我有几个基本问​​题:

在标题中假设以下声明:

@interface TestObject : NSObject {

    NSArray *myArray;
}

@property (nonatomic, retain) NSArray *myArray;

在实施中,我可以:

  1. 列表项
  2. 可以互换使用myArrayself.myArray来设置和获取目的吗?
  3. self.myArray = nil是否等同于[myArray release]
    如果是这样,是否有理由使用self.myArray = nil而不是[myArray release]

3 个答案:

答案 0 :(得分:5)

  1. myArrayself.myArray实际上是不同的。 myArray正在直接访问变量,而self.myArray(相当于[self myArray])正在调用访问器方法。大多数人都同意您应始终使用self.myArray(或[self myArray]),而不要直接使用myArray。这是因为访问者可能有副作用;例如,如果直接设置变量,KVO将无法工作,并且不会为您处理内存管理。

  2. 您的财产声明为retain,因此self.myArray = anArray(与[self setMyArray:anArray]相同)执行以下操作:

    1. 保留anArray,很快就会成为新的myArray。
    2. 释放旧的myArray,很快就不再是myArray。
    3. 更改指针myArray,使它现在指向anArray。
  3. 因此,当您执行self.myArray = nil时,其中一个步骤(#2)确实释放旧数组。 (并且由于新的nil,我们不必担心内存管理,即使我们保留了它。)所以是的,self.myArray = nil是有效的释放myArray的方式。

    但是,如果您正在谈论在myArray中发布dealloc,那么使用[myArray release]通常是个好主意,因为调用self.myArray = nil会产生副作用,如果有的话其他对象通过KVO观察myArray。因此,虽然确实遵循内存管理标准,但使用dealloc编写self.myArray = nil方法 是个好主意。

答案 1 :(得分:4)

现有的答案都是错误的。

@synthesize生成如下所示的setter和getter:

- (void)setMyArray:(NSArray*)array {
    if( myArray != array ) {
        [myArray release];
        myArray = [array retain];
    }
}

- (NSArray*)myArray {
    return myArray;
}

(注意,它们并不完全相同,如果指定副本或其他属性,则会有所不同,但这是基本公式)。现在我们可以看到self.myArray = nil;将释放旧数组。 self.myArray和myArray不能互换以进行设置。此外,self.myArray = nil;将继续在垃圾收集世界中工作。

正如Dave Delong所指出的那样,self.myArray = nil将通知任何观察myArray的人改变了值,如果你在dealloc方法中这样做可能会有问题。为了避免这种情况,你的dealloc看起来像:

- (void)dealloc {
    [myArray release]; myArray = nil;
    [super dealloc];
}

(注意myArray = nil;是一种风格选择。)

答案 2 :(得分:-3)

要设置setter / getters,你必须在main中实现这些:

+ (NSArray*) myArray {
return myArray;
}

+ (void) setMyArray:(NSArray*)input{
myArray = input;
}