作者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/cn.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