Nelson 寫些 iOS 開發的東東

千萬不要為了懶惰而用 new

| Comments

我們公司的 APP 一開始是請外包團隊幫忙開發,後來才找正職工程師進去維護的。不得不說,那個外包團隊的 iOS APP 工程師素質真的不怎麼樣,程式碼裡頭用了許多應該避免的寫法,其中一個就是它們大量的使用 [XXXObject new]

[XXXObject new] 其實是一個語法糖,它實際上會幫你轉成 [[XXXObject alloc] init],那這樣會有什麼問題呢?問題在於,我們在 init 時通常都需要傳入一些參數,而且很多時候該物件的 designated initializer 並不是 init。舉例來說,UITableViewControllerinitWithStyle:(UITableViewStyle)styleUIViewinitWithFrame:(CGRect)frame

所以偷懶用 new 的話,很有可能產生出來的物件會跟你預期的不一樣。我們的 APP 在 iOS 8 底下整個畫面爛掉,就是因為這個原因。

我們在建立 UIView 及其子類別(像是 UILabelUIButton)時都很偷懶的用了 new,就如同我剛剛提到的,它會被自動轉成 [[ alloc] init],對 UIView 而言如果沒有指定 frame,那就會當作是 initWithFrame:CGRectZero。所以簡而言之,透過 new 產生的 UIView 都變成了沒有大小。

雖然我們在建立 UIView 之後都還會用 auto layout 去設定它的尺寸與位置,但不知道是 iOS 8 的限制比較嚴格還是怎麼樣,原本在 iOS 7 底下可以正常顯示的畫面,在 iOS 8 底下都走樣了。解決方法也很簡單,乖乖的給它一個初始尺寸,再用 auto layout 去設定 constraints 即可。

總歸一句話,寫程式還是嚴謹一點比較好,不要為了少打幾個字而偷懶,很多的 bug 都是偷懶引起的~


Update: 補上一些為何我不建議用 new 的看法

為什麼即使在某些情況下是可以用 new 的,我還是會建議完全不要用呢,主要是因為以下幾點:

  1. 不是每個人都知道 new 做了什麼事,尤其是新手更有可能不知道,新手們可能看著前人都這樣用就跟著用了,結果在不該用的時候也用,那就麻煩了。
  2. 其實節省那幾個字沒什麼意思,再加上 Xcode 的 auto complete 可以幫忙補上,所以兩者打字的速度對我來說是一樣的。
  3. 明確地 (explicitly) 打出要使用的函式有助於讓新手熟悉,也能提高程式可讀性與減少不確定性,你不用去猜它到底會怎麼 init。
  4. 減少莫名其妙的 bug,例如我這篇文章所提到的。

所以我認為不用 new 而是用明確的 alloc init(WithXxx),是利大於弊的。

objective-c iOS8

Comments

comments powered by Disqus