作者uranusjr (←這人是超級笨蛋)
看板MacDev
標題Re: alloc和init 的指令
時間Mon Jul 14 23:49:52 2014
※ 引述《uranusjr (←這人是超級笨蛋)》之銘言:
1F:推 chlorine:上網看了一下,發現這是obc特殊的規則,alloc後要init 07/14 20:40
2F:推 Blueshiva:其實alloc作用上等同於malloc,而init則是類似建構子 07/14 23:03
3F:→ 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 那麼赤裸裸把它秀給你看而已
--
Les grandes et les meilleurs
tone from "Zadok the Priest"
Eine grosse stattliche Veranstaltung
by F. Handel
THE MAIN EVENT! These are the men
Sie sind die Besten
"Champions League" by Tony Britten THESE ARE THE CHAMPIONS!
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 218.161.94.175
※ 文章網址: http://webptt.com/m.aspx?n=bbs/MacDev/M.1405352995.A.DD3.html
※ 編輯: uranusjr (218.161.94.175), 07/14/2014 23:57:42
4F:→ Killercat:我其實都用new耶 幹嘛用alloc自虐? XD 07/15 11:02
5F:推 Blueshiva:嗯,我的講法其實是針對有C++經驗的人來講的,詳細講起 07/15 11:08
6F:→ Blueshiva:的確就像你說的,其實alloc+init才會等同於建構子 07/15 11:10
7F:→ Blueshiva:不過考量到ObjC設計的時候其實根本沒有C++,ObjC也是整 07/15 11:11
8F:→ Blueshiva:個用C組出來,我想的時候會把它用struct來想 07/15 11:13
9F:推 chlorine:一個程式,各自表述囉,我的書上是這樣教的呀 07/15 23:07
10F:推 Killercat:其實我問過一些同僚,因為很多人會override init 07/16 03:15
11F:→ Killercat:用[[AClass alloc]init]會比較讓人真的有call到init的 07/16 03:15
12F:→ Killercat:安心感 [AClass new]總覺得怕init沒跑到(他真的這樣講) 07/16 03:16
13F:推 Blueshiva:不過init也有很多種,常見的如initWithFrame,用new的話 07/16 14:25
14F:→ Blueshiva:應該就不會呼叫到? 07/16 14:25
15F:→ Killercat:這可能要試一下,不過這很妙的是,google查NSView.m 07/16 16:55
16F:→ Killercat:可以發現幾份實作,openstep的會呼叫[super init]而其他 07/16 16:56
17F:→ Killercat:實作則否。但是的確,所有實作都不會呼叫[self init] 07/16 16:56
18F:→ Killercat:所以你這句話這樣看來應該是對的... 07/16 16:57
19F:→ Killercat:大多數的NSView -(id)init實作都是 07/16 16:57
20F:→ Killercat:[self initWithFrame: NSZeroRect] 07/16 16:57
21F:→ Killercat:少部分則是反過來呼叫,這真的也滿妙的... 07/16 16:58
22F:→ uranusjr:阿婆的文件說 -initWithFrame: 是 designated initialzer 07/16 17:49
23F:→ uranusjr:所以讓 -init 呼叫 -initWithFrame: 才是對的 07/16 17:49
24F:→ uranusjr:當然實務上隨便搞也沒人阻止你, 只是蘋果應該不是這樣做 07/16 17:50
25F:→ Killercat:這其實有些問題 因為NSObject沒有initWithFrame 07/16 18:19
26F:→ Killercat:不過既然apple這樣講 就跟著這樣做吧... :D 07/16 18:19
27F:推 Blueshiva:文件上是說NSView的designated initialzer是 07/16 23:49
28F:→ Blueshiva:-initWithFrame,而且有說這是特殊狀況(應該是說相對於 07/16 23:49
29F:→ Blueshiva:其他種類的class),有點類似C++中建構子多載的情況吧 07/16 23:51
30F:→ Blueshiva:針對不同用途的物件,有個最終的initializer,其餘的就 07/16 23:52
31F:→ Blueshiva:是一直丟預設值往後呼叫 07/16 23:52