Re: alloc和init 的指令

作者: uranusjr (←這人是超級笨蛋)   2014-07-14 23:49:52
※ 引述《uranusjr (←這人是超級笨蛋)》之銘言:
推 chlorine:上網看了一下,發現這是obc特殊的規則,alloc後要init 07/14 20:40
推 Blueshiva:其實alloc作用上等同於malloc,而init則是類似建構子 07/14 23:03
→ Blueshiva:畢竟ObjC是建構在C之上,物件的初始化不像C++寫在一起 07/14 23:04
說這是 Objective-C 特殊的規則其實不太對
因為這是物件導向語言共通的規則, 只是 Objective-C 的表現比較 explicit
絕大多數的類似語言都有同樣的做法
例如 Python 的物件建立其實也有 __new__ 和 __init__ 兩個步驟
只是一般會用特殊語法 instance = Class() 一次做掉
但事實上它背後仍然是呼叫 allocator + inistializer 的形式
其實這就和 NSObject 的 +new method 差不多 (不知道有多少人知道這個 method)
只是 Python 允許你換掉 method 參數
所以可以用一個語法自動做完, 不需要像 Objective-C 分兩次
即使是 C++, 其實狀況還是一樣
雖然一般的做法都是把 allocation 和 initialization 一起放在 contructor
但是在有繼承的狀況下, constructor 其實沒辦法取代 initializer
例如 C++ 不能在 constructor 呼叫 virtual functions
因為在子類別的 allocation 完成之前無法使用 vtable
其他語言也會有各自的 quirks 讓它們需要把 initializer 獨立出來
相對地, Objective-C 因為分兩個步驟, 就不會有這個問題
因為在 initializer 執行時已經保證 allocation 完成
所以可以安全使用任何子類別的複寫
總之 allocator 與 initializer 分開不是 Objective-C 的專利
而是物件導向語言在底層實作必要的設計
只是不是每個語言都像 Objective-C 那麼赤裸裸把它秀給你看而已
作者: chlorine (綠)   2014-07-14 20:40:00
上網看了一下,發現這是obc特殊的規則,alloc後要init
作者: Blueshiva (龍野南雲)   2014-07-14 23:03:00
其實alloc作用上等同於malloc,而init則是類似建構子畢竟ObjC是建構在C之上,物件的初始化不像C++寫在一起
作者: Killercat (殺人貓™)   2014-07-15 11:02:00
我其實都用new耶 幹嘛用alloc自虐? XD
作者: Blueshiva (龍野南雲)   2014-07-15 11:08:00
嗯,我的講法其實是針對有C++經驗的人來講的,詳細講起的確就像你說的,其實alloc+init才會等同於建構子不過考量到ObjC設計的時候其實根本沒有C++,ObjC也是整個用C組出來,我想的時候會把它用struct來想
作者: chlorine (綠)   2014-07-15 23:07:00
一個程式,各自表述囉,我的書上是這樣教的呀
作者: Killercat (殺人貓™)   2014-07-16 03:15:00
其實我問過一些同僚,因為很多人會override init用[[AClass alloc]init]會比較讓人真的有call到init的安心感 [AClass new]總覺得怕init沒跑到(他真的這樣講)
作者: Blueshiva (龍野南雲)   2014-07-16 14:25:00
不過init也有很多種,常見的如initWithFrame,用new的話應該就不會呼叫到?
作者: Killercat (殺人貓™)   2014-07-16 16:55:00
這可能要試一下,不過這很妙的是,google查NSView.m可以發現幾份實作,openstep的會呼叫[super init]而其他實作則否。但是的確,所有實作都不會呼叫[self init]所以你這句話這樣看來應該是對的...大多數的NSView -(id)init實作都是[self initWithFrame: NSZeroRect]少部分則是反過來呼叫,這真的也滿妙的...
作者: uranusjr (←這人是超級笨蛋)   2014-07-16 17:49:00
阿婆的文件說 -initWithFrame: 是 designated initialzer所以讓 -init 呼叫 -initWithFrame: 才是對的當然實務上隨便搞也沒人阻止你, 只是蘋果應該不是這樣做
作者: Killercat (殺人貓™)   2014-07-16 18:19:00
這其實有些問題 因為NSObject沒有initWithFrame不過既然apple這樣講 就跟著這樣做吧... :D
作者: Blueshiva (龍野南雲)   2014-07-16 23:49:00
文件上是說NSView的designated initialzer是-initWithFrame,而且有說這是特殊狀況(應該是說相對於其他種類的class),有點類似C++中建構子多載的情況吧針對不同用途的物件,有個最終的initializer,其餘的就是一直丟預設值往後呼叫

Links booklink

Contact Us: admin [ a t ] ucptt.com