楼主:
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 那么赤裸裸把它秀给你看而已
上网看了一下,发现这是obc特殊的规则,alloc后要init
其实alloc作用上等同于malloc,而init则是类似建构子毕竟ObjC是建构在C之上,物件的初始化不像C++写在一起
嗯,我的讲法其实是针对有C++经验的人来讲的,详细讲起的确就像你说的,其实alloc+init才会等同于建构子不过考量到ObjC设计的时候其实根本没有C++,ObjC也是整个用C组出来,我想的时候会把它用struct来想
其实我问过一些同僚,因为很多人会override init用[[AClass alloc]init]会比较让人真的有call到init的安心感 [AClass new]总觉得怕init没跑到(他真的这样讲)
不过init也有很多种,常见的如initWithFrame,用new的话应该就不会呼叫到?
这可能要试一下,不过这很妙的是,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: 才是对的当然实务上随便搞也没人阻止你, 只是苹果应该不是这样做
这其实有些问题 因为NSObject没有initWithFrame不过既然apple这样讲 就跟着这样做吧... :D
文件上是说NSView的designated initialzer是-initWithFrame,而且有说这是特殊状况(应该是说相对于其他种类的class),有点类似C++中建构子多载的情况吧针对不同用途的物件,有个最终的initializer,其余的就是一直丢默认值往后呼叫