當前位置:成語大全網 - 新華字典 - 為什麽代理不能使用保留屬性

為什麽代理不能使用保留屬性

在妳開始寫iOS程序後不久,妳應該開始面對很多委托。

無論是使用別人的庫還是編寫自己的庫,都無法逃脫delegate。

以防有人不知道什麽是delegate,這裏簡單介紹壹下。

Delegate中文稱為delegate,通常在類中使用,將壹些事件處理“委托”給其他人完成。

例如,xml解析器可能知道如何解析xml,但是XML解析器可能不知道如何處理解析所學的內容。

因此NSXMLParser提供了壹個NSXMLParserDelegate供客戶端實現。

當parse轉到壹個元素時,回調委托定義的消息,

讓他的客戶自己決定如何處理這個元素。

好吧,我承認我的解釋很模糊,但是我的文章並不是為了讓妳理解什麽是delegate。

它針對的是妳在使用或設計delegate時可能需要註意的事情。

當在我們的類中設計委托時,我們通常有幾個考慮因素。

假設我的類被稱為我的類,那麽我們可以定義壹個MyClassDelegate作為我的委托協議。

在我的課堂上,我們可能會這樣寫。

@ protocol MyClass delegate-(void)myclassomeevent:(my class *)my class;@ end @ interface my class { MyClass delegate _ delegate;} @property (nonatomic,assign)委托;@end

在上面的代碼中,我們註意到delegate被定義為@property (assign)。

為什麽不用assign代替retain?

原因是在iOS的引用計數環境下,必須解決循環計數的問題。

讓我們寫壹下我們通常如何使用委托。我想下面這段代碼大家應該都不陌生。

-(void)some action { my class =[my class new];myClass.delegate = self....}

這裏很快會出現循環引用。

假設上面的代碼是在myViewController的對象中編寫的,

壹旦myViewController的引用計數變為1,

MyViewController和myClass這兩個兄弟互相保留在後面,成了孤島,也造成了內存泄漏!!!

正因為如此,官方的iOS文檔會建議所有的delegate應該使用assign property。

即所謂的“弱引用”屬性,其特點是雖然會持有對方的引用,但不會增加retain計數。

這樣,當myViewController的retainecount變為0時,就會被dealloc。

同時,在dealloc中,我的類也被釋放,我的類也被釋放。

-(void)dealloc {[my class release];【超級dealloc】;}

會結束嗎?還沒有...

這裏還有壹個大家經常忘記的重點,就是上面的dealloc是有潛在危險的。

應該改成這個

-(void)deal loc { my class . delegate = nil;【myClass發布】;【超級dealloc】;}

您可能想知道,我的類不是很快就要發布了嗎?為什麽先將他的委托設置為零?

這是因為我們假設我的類將很快被dealloc,但現實不壹定如此。

有可能它內置了壹個NSURLConnection,或者正在做壹些事情,其他對象也保留在我的類中。

如果myClass沒有立即dealloc,他的myClass.delegate不是指向了非法位置嗎?(這種指針叫做懸空指針。)

解決方案在MyViewController的dealloc中,在發布myClass之前,

您應該首先將最初指向您的委托更改為nil,以避免崩潰。

在我之前寫的項目中,很大壹部分crash就是這樣造成的,因為這個問題通常不會每次都出現。

但真的發生了就很難重現了,不可大意。

但我很興奮,這個問題在iOS5中可以通過自動引用計數得到改善。

在ARC中提出了弱引用的新概念來代替原來的賦值。

如果弱引用所指向的對象由於零retainmount而被釋放,則弱引用被自動設置為nil。

舊的assign做法在ARC中稱為__unsafe_unretained,這只是為了兼容iOS4以下的版本。

回顧要點:

如果妳正在為別人寫壹個庫,記得設置妳的委托來分配屬性,這樣就不會引起循環引用。

當妳想開始使用別人的庫時,記得在dealloc中設置delegate為nil以避免崩潰。