关于Objective-C属性语法的基本问题
关于目标C中属性的语法和用法,我有几个基本问题: 假设标题中有以下声明:关于Objective-C属性语法的基本问题,objective-c,cocoa,cocoa-touch,Objective C,Cocoa,Cocoa Touch,关于目标C中属性的语法和用法,我有几个基本问题: 假设标题中有以下声明: @interface TestObject : NSObject { NSArray *myArray; } @property (nonatomic, retain) NSArray *myArray; 在实施过程中,我可以: 列表项 可交替使用myArray和self.myArray进行设置和获取 self.myArray=nil是否等同于[myArray发行版]? 如果是这样,是否有理由使用self.m
@interface TestObject : NSObject {
NSArray *myArray;
}
@property (nonatomic, retain) NSArray *myArray;
在实施过程中,我可以:
myArray
和self.myArray
进行设置和获取self.myArray=nil
是否等同于[myArray发行版]
?如果是这样,是否有理由使用
self.myArray=nil
而不是[myArray release]
要设置setter/getter,您必须在main中实现它们:
+ (NSArray*) myArray {
return myArray;
}
+ (void) setMyArray:(NSArray*)input{
myArray = input;
}
现有的两个答案都是错误的 @合成生成如下所示的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;
是这里的风格选择。)
myArray
和self.myArray
实际上是不同的myArray
直接访问变量,而self.myArray
(相当于[self myArray]
)调用访问器方法。大多数人都同意你应该一直使用self.myArray
(或[self-myArray]
),而不要直接使用myArray
。这是因为访问者可能有副作用;例如,如果直接设置变量,KVO将不起作用,内存管理也不会为您处理
您的属性是用retain
声明的,因此self.myArray=anArray
(与[self-setMyArray:anArray]
相同)执行以下操作:
保留anArray,它将很快成为新的myArray
释放旧的myArray,它很快将不再是myArray
更改指针myArray,使其现在指向数组
因此,当您执行self.myArray=nil
时,其中一个步骤(#2)实际上是释放旧数组。(因为新的是nil
,我们不必担心它的内存管理,即使我们保留了它。)所以是的,self.myArray=nil
是释放myArray
的有效方法
但是,如果您在dealloc
中谈论释放myArray
,通常最好使用[myArray release]
,因为调用self.myArray=nil
会产生副作用,如果任何其他对象通过KVO观察myArray
。因此,虽然遵循内存管理标准,但使用self.myArray=nil
编写dealloc
方法并不是一个好主意。我知道我需要在实现中包含synthesis语句。-1 setter/getter方法是实例方法,不是类方法。这也是不正确的。您的方法(除了类方法而不是实例方法)正在执行简单的指针赋值,就好像属性被声明为assign
。事实并非如此。它被声明为retain
如果其他人正在观察myArray
属性,则code>可能会产生不良副作用。您不希望在对象解除分配时触发观察通知,因为这样,观察者可能会尝试访问部分解除分配的对象。这不是一个好主意。戴夫·德隆:正在解除分配的对象不应该有任何观察者。如果是这样的话,这本身就是程序中的一个bug。这是因为使用访问器可能会产生令人满意的副作用,包括(但不限于)KVO和内存管理。假设您已经在myArray
中设置了retain
-ed数组。然后设置myArray=newArray
会泄漏旧的,而调用访问器(self.myArray=newArray
)会释放旧的并保留新的。@JK可以随意使用self.myArray=nil代码>除了你的dealloc
方法之外的任何地方。要完全学究化;),步骤2.2仅当旧myArray与新myArray不同时才释放它。@JK从不自己调用DEALLOC(除非它是DEALLOC
方法中的[super DEALLOC]
)。这就是retain
和release
的目的。而YVN22:我同意你不应该从dealoc
向自己发送访问者消息,因为访问者方法本身可能有副作用,但如果你在对象点击dealoc
时仍在观察对象的属性,那就是一个bug。