Re: alloc和init 的指令

看板MacDev作者 (←這人是超級笨蛋)時間11年前 (2014/07/14 23:49), 11年前編輯推噓5(5023)
留言28則, 4人參與, 最新討論串3/4 (看更多)
※ 引述《uranusjr (←這人是超級笨蛋)》之銘言:

07/14 20:40,
上網看了一下,發現這是obc特殊的規則,alloc後要init
07/14 20:40

07/14 23:03,
其實alloc作用上等同於malloc,而init則是類似建構子
07/14 23:03

07/14 23:04,
畢竟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://www.ptt.cc/bbs/MacDev/M.1405352995.A.DD3.html ※ 編輯: uranusjr (218.161.94.175), 07/14/2014 23:57:42

07/15 11:02, , 1F
我其實都用new耶 幹嘛用alloc自虐? XD
07/15 11:02, 1F

07/15 11:08, , 2F
嗯,我的講法其實是針對有C++經驗的人來講的,詳細講起
07/15 11:08, 2F

07/15 11:10, , 3F
的確就像你說的,其實alloc+init才會等同於建構子
07/15 11:10, 3F

07/15 11:11, , 4F
不過考量到ObjC設計的時候其實根本沒有C++,ObjC也是整
07/15 11:11, 4F

07/15 11:13, , 5F
個用C組出來,我想的時候會把它用struct來想
07/15 11:13, 5F

07/15 23:07, , 6F
一個程式,各自表述囉,我的書上是這樣教的呀
07/15 23:07, 6F

07/16 03:15, , 7F
其實我問過一些同僚,因為很多人會override init
07/16 03:15, 7F

07/16 03:15, , 8F
用[[AClass alloc]init]會比較讓人真的有call到init的
07/16 03:15, 8F

07/16 03:16, , 9F
安心感 [AClass new]總覺得怕init沒跑到(他真的這樣講)
07/16 03:16, 9F

07/16 14:25, , 10F
不過init也有很多種,常見的如initWithFrame,用new的話
07/16 14:25, 10F

07/16 14:25, , 11F
應該就不會呼叫到?
07/16 14:25, 11F

07/16 16:55, , 12F
這可能要試一下,不過這很妙的是,google查NSView.m
07/16 16:55, 12F

07/16 16:56, , 13F
可以發現幾份實作,openstep的會呼叫[super init]而其他
07/16 16:56, 13F

07/16 16:56, , 14F
實作則否。但是的確,所有實作都不會呼叫[self init]
07/16 16:56, 14F

07/16 16:57, , 15F
所以你這句話這樣看來應該是對的...
07/16 16:57, 15F

07/16 16:57, , 16F
大多數的NSView -(id)init實作都是
07/16 16:57, 16F

07/16 16:57, , 17F
[self initWithFrame: NSZeroRect]
07/16 16:57, 17F

07/16 16:58, , 18F
少部分則是反過來呼叫,這真的也滿妙的...
07/16 16:58, 18F

07/16 17:49, , 19F
阿婆的文件說 -initWithFrame: 是 designated initialzer
07/16 17:49, 19F

07/16 17:49, , 20F
所以讓 -init 呼叫 -initWithFrame: 才是對的
07/16 17:49, 20F

07/16 17:50, , 21F
當然實務上隨便搞也沒人阻止你, 只是蘋果應該不是這樣做
07/16 17:50, 21F

07/16 18:19, , 22F
這其實有些問題 因為NSObject沒有initWithFrame
07/16 18:19, 22F

07/16 18:19, , 23F
不過既然apple這樣講 就跟著這樣做吧... :D
07/16 18:19, 23F

07/16 23:49, , 24F
文件上是說NSView的designated initialzer是
07/16 23:49, 24F

07/16 23:49, , 25F
-initWithFrame,而且有說這是特殊狀況(應該是說相對於
07/16 23:49, 25F

07/16 23:51, , 26F
其他種類的class),有點類似C++中建構子多載的情況吧
07/16 23:51, 26F

07/16 23:52, , 27F
針對不同用途的物件,有個最終的initializer,其餘的就
07/16 23:52, 27F

07/16 23:52, , 28F
是一直丟預設值往後呼叫
07/16 23:52, 28F
文章代碼(AID): #1Jm_mZtJ (MacDev)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 3 之 4 篇):
文章代碼(AID): #1Jm_mZtJ (MacDev)