假设我有两个班级。在第一篇中,我在Class1.h
中声明了这一点@interface Class1 : UIViewController {
NSString *myString;
id myObject;
}
在第二节课上我超越了我宣称它就像
@interface Class2 : UIViewController {
NSString *myString;
id myObject;
}
@property (nonatomic, retain) NSString *myString;
@property (nonatomic, retain) id myObject;
然后我在Class2.m上 @synthesize myString,myObject
然后,在我的主程序中,我创建了两个对象:一个基于Class1,另一个基于Class2。
class2的@property会有什么影响?是否始终保留分配给Class2上的两个值的每个值?如果是这样,我是否需要“释放”它们?怎么样?
感谢。
答案 0 :(得分:3)
请阅读Declared Properties section of The Objective-C programming language 有关属性的完整说明;)
在Class2中:
在这种情况下,您将retain
属性设置为您的属性,它应该保留在实现中。合成属性时会自动完成此操作。
这意味着你应该
- (void) dealloc{
[myString release];
[myObject release];
[super dealloc];
}
一切都应该没问题
在Class1中,您没有属性,因此从外部看不到myString和myObject。但这并不意味着你不应该释放它们。这取决于您初始化它们的方式和/或是否向它们发送保留消息。
顺便说一句,如果你设置assign
属性而不释放它,只需在dealloc方法中将其设置为nil即可。如果您将copy
设置为它,则必须将其释放。
修改强>
你说:*但是假设我有这个*
@property (nonatomic, retain) UIView *myView;
和
myView = [[UIView alloc] initWithFrame:myFrame];
[self.view addSubview:myView];
[myView release];
?我已经发布了myView ...我是否必须再次发布它?
首先,由于您以这种方式定义了属性,因此您应该将dealloc方法设置为:
- (void) dealloc{
[myView release];
[super dealloc];
}
所以,答案是不,你不应该释放它,但实际上是不正确的。 请看一下:
myView = [[UIView alloc] initWithFrame:myFrame]; //myView retainCount is 1
[self.view addSubview:myView]; //retainCount is 2
[myView release]; //retainCount is 1 again
稍后在dealloc方法
- (void) dealloc{
[myView release]; // retainCount becomes 0, is deallocated
[super dealloc]; // subviews of self.view are released but myView was already deallocated!, so you have over released myView once ;(
}
这是正确的方法:(使用你的属性;))
UIView *aView = [[UIView alloc] initWithFrame:myFrame]; // init, retainCount is 1
self.myView = aView; // retainCount becomes 2
[aView release]; // retainCount becomes 1 again and we are fine.
[self.view addSubview:self.myView]; //retainCounts becomes 2 again.
即使它是2也没有问题,因为当取消分配self.view时,它的子视图也将被释放。因此,当self被释放时,self.myView retainCount将再次变为1。
- (void) dealloc{
[myView release]; //retainCounts becomes 1
[super dealloc]; // all its subviews of self.view are released hence myView retaincount becomes 1 and is released corretly
}
有什么区别?
假设self.myView也被其他对象X保留,并且使用前一种方法,X的视图将指向无效对象,因为它已经被释放。
希望有所帮助
<强> EDIT2 强> 作为bbum的指示,这是一个关于属性的迷你短小教程:
当你有
时@property (... retain) NSObject *retainVar;
@property (... assign) NSObject *assignVar;
@property (... copy) NSObject *copyVar;
你@synthesize他们
就像拥有以下setter:
// retain
-(void)setRetainVar:(NSObject *)var {
if (retainVar != var) {
[retainVar release];
retainVar = [var retain];
}
}
//assign
-(void)setAssignVar:(NSObject *)var {
assignVar = var;
}
//copy
-(void)setCopyVar:(NSObject *)var {
if (copyVar != var) {
[copyVar release];
copyVar = [var copy];
}
}
(这意味着如果直接分配一个对象,你必须确保它与上面的setter相同,从内存管理的角度来看)
你的dealloc方法应该是这样的:
- (void) dealloc{
[retainVar release];
assignVar = nil;
[copyVar release];
[super dealloc];
}
设置你的ivars时
例如,在init中:
- (id) init{
if ((self = [super init])){
//this is ok
retainVar = [[NSObject alloc] init];//but is retainVar was not nil we will have a leak ;(
//This is better
NSObject *obj = [NSObject alloc] init];
self.retainVar = obj;
[obj release];
//this is BAD
assignVar = [[NSObject alloc] init];//because this is like retaining it, later it will leak
//below is correct
NSObject *obj = [[[NSObject alloc] init] autorelease];
assignVar = obj;
//copy is pretty much like retain,
//this is ok
copyVar = [[NSObject alloc] init]; //but, if copyVar was not nil is a leak!
//below is better
NSObject *obj = [NSObject alloc] init]:
self.retainVar = obj;
[obj release];
}
return self;
}
答案 1 :(得分:1)
Apple的“学习目标C - 入门”会告诉您更多内容: