16.說一說iOS中與屬性成員相關的坑

       之前在做項目的時候遇到的屬性相關的一些坑,當時不求甚解,只要改好就ok,今天忽然看到了曾經遇到的坑的解釋,就在這裏做一個總結:

1.同時重寫屬性的get和set方法

       在.m中同時重寫get和set方法後,總是報錯,類似這個樣子:


         後來我通過加上@synthesize array = _array, 當時並不知道爲什麼會這樣,但今天看了下面這個面試題的回答有了明悟,原文如下:

在有了自動合成屬性實例變量之後,@synthesize還有哪些使用場景?

回答這個問題前,我們要搞清楚一個問題,什麼情況下不會autosynthesis(自動合成)?(實例變量 = 成員變量 = ivar

  • 同時重寫了setter和getter時

  • 重寫了只讀屬性的getter時

  • 使用了@dynamic時

  • 在 @protocol 中定義的所有屬性

  • 在 category 中定義的所有屬性

  • 重載的屬性

當你在子類中重載了父類中的屬性,你必須 使用@synthesize來手動合成ivar。

除了後三條,對其他幾個我們可以總結出一個規律:當你想手動管理@property的所有內容時,你就會嘗試通過實現@property的所有“存取方法”(the accessor methods)或者使用@dynamic來達到這個目的,這時編譯器就會認爲你打算手動管理@property,於是編譯器就禁用了autosynthesis(自動合成)。

因爲有了autosynthesis(自動合成),大部分開發者已經習慣不去手動定義ivar,而是依賴於autosynthesis(自動合成),但是一旦你需要使用ivar,而autosynthesis(自動合成)又失效了,如果不去手動定義ivar,那麼你就得藉助@synthesize來手動合成ivar。

     以上已經說的足夠明白,所以上面的錯誤也可以通過手動聲明一個_array的成員變量得到解決。

2.用copy關鍵字聲明NSArray與NSMutableArray屬性成員的一些問題:

       根據iOS裏一切皆對象,所以對於對象的賦值都是傳一個對象的引用,如果我想在賦值時想傳的是一個對象的拷貝副本,就要用到copy了。這裏的拷貝,有深拷貝和淺拷貝,關於這方面的知識,請看這裏:。當我們以關鍵字copy聲明NSArray與NSMutableArray屬性成員時,相當於在set方法中以前的直接_array = array賦值,變成了調用_array = [array  copy]進行賦值,這樣傳入的就是對象拷貝的副本,而不是引用。但是NSMutableArray屬性成員以copy聲明時,就會出現該屬性成員在增刪改查時會沒有對應的方法。原因就在於copy不論原來的是可變還是不可變,創建的都是不可變副本,而mutablecopy不論原來的是可變還是不可變,創建的都是可變副本。正是這個原因,導致NSMutableArray屬性成員在set方法之後變爲了不可變的NSArray,當然無法對其進行增刪改查了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章