2009-11-26 75 views
1

我有一段時間的iPhone開發工作。第一次,我對Objective-C中的內存管理感到很驚訝:)。但現在我瞭解了一點。如何釋放協議屬性?

問題是,有時候,我使用協議作爲類的屬性,因爲我認爲它的定義與C#或Java中的'interface'非常相似。如下所示。

@protocol Shield 
    ... 
@end 

// Interface 
@interface Dragon { 
    id<Shield> shield 
    NSString * name; 
} 

@property (nonatomic,retain) id<Shield> shield; 
@property (nonatomic,retain) NSString * name; 

@end 

但我總是釋放dealloc()方法中的任何屬性對象。如下所示。

-(void)dealloc { 
    [name release]; 
    [shield release]; // <--- Totally impossible. xcode said '-release not found in protocol' 
    [super dealloc]; 
} 

如您所見,我無法釋放協議。那麼這會導致我未來的記憶問題?你有另一種方式來處理這個解決方案來給我建議嗎?

+0

下面iKenndac的回答是正確的方法。或者,您可以將ID轉換爲符合NSObject協議的ID並調用發佈方法。 '[(id nash 2009-11-26 12:59:11

回答

8

您需要定義你的協議作爲秉承NSObject協議,像這樣:

@protocol Shield <NSObject> 
    ... 
@end 

很簡單,當你知道如何! ;-)

編輯:另外,你是正確的 - Objective-C中的協議相當於Java和C#中的接口。

另一個編輯:它可能會讓你覺得很奇怪,但Objective-C允許使用多個根對象,所以你實際上不能保證每個對象都會從NSObject下降。由於release是一個NSObject方法,因此您必須將協議定義爲遵循<NSObject>協議,然後才能確定它能夠響應release方法。

1

1的做,而不是[屏蔽發行]正確的做法是設置

self.shield = nil; 

2,也改變

@property (nonatomic,retain) id<Shield> shield; 

@property (nonatomic,assign) id<Shield> shield; 

那麼你的罰款。

編輯:

您避免保留 代表的原因是,你需要避免 保留循環:

A創建BA將自身設置爲B的 代表...... A被公佈了業主

。如果B保留了A,A就不會 釋放,B擁有A,因此A的 的dealloc將永遠不會被調用, 導致A和B都泄漏。

你不應該擔心A走開 B/C它擁有B,從而在dealloc中擺脫它 。

Why are Objective-C delegates usually given the property assign instead of retain?

請參閱的示例協議聲明的UITableView類參考:

@屬性(非原子,分配)ID <的UITableViewDelegate>委託

+0

直接釋放成員沒有任何錯誤。如果有人使用uitableviews,他們會在運行時得到錯誤,並更改屬性來分配內存泄漏(如果屏蔽被保留)或運行時出現錯誤(如果您只是指定屏蔽自動釋放對象) – Vladimir 2009-11-26 14:33:13

+0

。我現在明白了。請參閱 http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html – 2009-11-26 15:30:52

+0

請同時看看我的最終編輯 – 2009-11-26 15:35:59