請仔細閱讀Declared Properties section of The Objective-C programming language 對性能的完整說明;)
在等級2:
在這種情況下,您將retain
屬性設置爲您的財產,它應該保留在實施中。這是在您合成屬性時自動完成的。 這意味着你應該有
- (void) dealloc{
[myString release];
[myObject release];
[super dealloc];
}
,一切都應該罰款
在Class,你沒有屬性,這樣的myString和myObject的從外面是不可見的。但這並不意味着你不應該釋放它們。這取決於你初始化他們的方式和/或你是否發送留言給他們。
順便說一句,如果你設置了一個屬性,你不會釋放它,只需在dealloc方法中將它設置爲零即可。如果您將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.myView retainCount將在稍後釋放self時再次變爲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他們
就像擁有以下設置者:
// 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];
}
}
(這意味着如果你直接分配一個對象,你必須確保的東西等同於上面制定者,從內存管理點)
和你的dealloc方法應該是這樣的:
- (void) dealloc{
[retainVar release];
assignVar = nil;
[copyVar release];
[super dealloc];
}
當初始化設置裏面的高德
例如:
- (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;
}
您需要討論兩者之間的區別。直接設置實例變量,並通過setter/getter來保留/釋放。事實上,這是誤導。 – bbum 2011-01-30 18:16:08