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