2011-01-30 56 views
0

假設我有兩個類。在第一個我宣佈這Class1.hiphone - 試圖瞭解@property

@interface Class1 : UIViewController { 

    NSString *myString; 
    id myObject; 

} 

在第二類我點到爲止,我宣佈它像

@interface Class2 : UIViewController { 

    NSString *myString; 
    id myObject; 

} 

@property (nonatomic, retain) NSString *myString; 
@property (nonatomic, retain) id myObject; 

,然後我@synthesize MyString的,在等級2 myObject的。 m

然後,在我的主程序中,我創建了兩個對象:一個基於Class1,另一個基於Class2。

class2的@property會有什麼影響?分配給Class2上的兩個值的每個值是否始終保留?如果是這樣,我需要「釋放」它們嗎?怎麼樣?

謝謝。

回答

3

請仔細閱讀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; 
} 
+1

您需要討論兩者之間的區別。直接設置實例變量,並通過setter/getter來保留/釋放。事實上,這是誤導。 – bbum 2011-01-30 18:16:08