1. 程式人生 > >iOS中self.property 和_property的區別,init和dealloc為何避免用self.property

iOS中self.property 和_property的區別,init和dealloc為何避免用self.property

一、self.property訪問

1、self.property 經過oc訊息派發,可以完成屬性所定義的“記憶體管理語義”, 例如copy屬性;

2、通過屬性訪問,可以設定斷點除錯。

 

二、_property直接訪問例項變數

1、_property直接訪問例項變數,不經訊息派發訪問速度更快;

2、直接訪問例項變數,不會觸發KVO;

3、直接訪問例項變數,不會呼叫設定方法,繞過了相關屬性定義的“記憶體管理語義”,例如在ARC中,直接訪問copy屬性的例項變數,不會拷貝而是直接覆蓋。

 

結論:

寫入例項變數時,通過self.property

來做;而在讀取的時候,_property直接訪問的方式。既可以提高讀取操作速度,又能控制對屬性的寫入,保證相關屬性的“記憶體管理語義”。

 

 

三、注意點

1、懶載入,必須通過獲取方法來訪問屬性

- (NSArray *)array{

     if(!_array){

          _array = [[NSArray alloc] init];

    }

    return _array;

}

 

2、不要在init和dealloc中使用self.property

        在init中,進行初始化首選會呼叫  self = [super init](注意這裡只是子類呼叫了父類的init方法,並不是把父類返回給子類的self,self是物件指標,super只是個識別符號,跟self不是一種型別的東東,這裡self是子類的物件指標,哪怕呼叫到了父類的init方法,父類init中的self還是指向子類的物件,因此在父類中呼叫到了子類的過載方法); 即子類先呼叫父類init方法,如果父類在init中使用了 self.property,一旦子類重寫了 self.property的該方法,那麼由於多型父類中呼叫的其實是子類的accessor方法(即self.propert方法),而此時只是在進行父類初始化,子類初始化還未完成,呼叫子類的accessor可能會造成崩潰。現實中更多的是某個方法被少呼叫一次,出現邏輯錯誤。

        在銷燬子類物件時,首先是呼叫子類的dealloc,最後呼叫父類的dealloc(這與init相反,在ARC中不需要我們手動呼叫[super dealloc], 系統會在子類dealloc的最後自動呼叫父類dealloc)。如果在父類dealloc呼叫了accessor且該accessor被子類重寫,就會呼叫到子類斷點accessor。但此時子類已經釋放,就會出現錯誤甚至崩潰。

         這篇文章解釋得很好,見連結: http://www.jianshu.com/p/3cf3f5007243