給 iOS 新手的 property & attribute 整理

威廉
5 min readJan 11, 2018

--

property 是什麼

getter/setter 是物件存取內部實例變數的方法,而 property 則是 Objective-C 將固定格式的 getter/setter 標準化後的 「一種更便利的實例變數存取方式」

功能

  • 自動生成 getter/setter 和實例變數
  • 點語法 (.) 存取實例變數
  • attribute 描述變數的存取狀態和方式

property 怎麼用

不使用 property 時

實例變數需要自己宣告, getter/setter 也要自己撰寫。

使用 property 後

可以大幅精簡為:

實際使用的例子:

顯然能幫助減少程式碼行數。

點語法的問題

點語法是很棒的語法糖,它讓 Objective 的語法看起來短一點,
如果你寫過其他語言,也會覺得點語法比方括號的語法親切許多。
但它的易用也帶來了一些可能踩到的陷阱。

覆寫 setter 時造成無窮迴圈

有時候我們雖然用了 Property ,但還是想要覆寫 getter/setter:

但如果在 setter 當中用了 self. 這種點語法,
就會在這個 setter 中又呼叫了一次 setter (自己),形成無窮迴圈。
如果你不覆寫 setter/getter,也不要自己重新宣告實例變數的話,
property 會全部幫你處理掉,讓你省下不少心。

用 getter 時以為在用 structure

想改變一個 View 的 x 值,可能會想這樣寫:

view.frame.orgin.x = 0.0;

但這樣是沒有用的,因為這段程式碼實際上是:

[view frame].origin.x

拆解來看,[view frame] 表示 frame 是 view 的 property,
而 origin 和 x 調用時是 structure。

當你想要用 setter 設值給這個 x 的時候, 因為 frame 是用 getter 取得的,
沒有把 frame 指定給某個變數的話會消失,因此這樣的設值方式會造成編譯錯誤。

正確的做法是,直接設值給 view 的 frame property:

property 的 attribute

atomic

atomic 的意思是保證這個存取一定可以存取到合法的值。
如果現在有兩個 thread,一個 read thread、一個 write thread,
而他們對某變數的存取在同一時間碰上了,那麼 atomic 保證 read thread 取的值, 一定是 write thread 修改前或修改後的正常值,而不會是奇怪的記憶體位置。

nonatomic

nonatomic 不保證存取一定可以存取到正常的值,
但也因為這樣不需要將存取的位址像 atomic 一樣鎖定,從而提升了速度。
一般寫 iOS 的時候不常需要考慮到兩個 thread 存取同一值衝突的情況,
所以不需要考慮 thread-safe 的物件都可以使用 nonatomic。

readwrite

表提供 setter / getter。

readonly

表只提供 getter,這邊有趣的是可以將一個變數設為 readonly,
但是在類目中重新定義它為 readwrite,就可以在內部讀寫那個變數。

記憶體管理 (ARC)

Objective-C 的物件回收機制就是判斷一個物件的持有者有幾個,
當一個物件沒有任何持有者時,就會回收該物件。
使用 ARC 就可以不用像 MRC 時候像神經病一樣 retain, release,
只要設定好正確的存取關係即可。

assign

用於基礎資料型別,比如 NSInteger、CGFloat 和 C的資料類型 (int, double)等等。 這個屬性所規範的資料型別不需牽扯到任何記憶體管理。

strong

預設的存取類型,表示持有關係。
當一個物件被別的物件持有時,它的 reference count 會被加一,
確保這個物件不會在還被其他物件需要時,就被釋放記憶體。

weak

表示非持有關係,當一個物件被別的物件以 weak 方式指向時, 它的 reference count 不會被加一,也就是說, 當此物件不再被其他物件需要時,即使有別的物件用 weak 方式連結它,
這個物件也會被釋放記憶體。

copy

表示當 setter 拿到值的時候,拷貝一份得到的物件。
拷貝後將拷貝的物件 retain,因此就算原有的物件發生改動,
也不會影響到現有的 copy 物件。

Copy 使用時該物件需要符合 「NSCopying Protocol」,最常用於 NSString。

參考文章:

KKBOX iOS/Mac OS X 基礎開發教材

Property and Synthesize — 高見龍

Effective Objective-C 2.0 中文版:改善iOS與OSX程式的52個具體做法

--

--