鉴客 浅谈 Objective-C 下对象的初始化
2014-01-20 18:02
246 查看
众所周知,Objective-C是一门面向对象的语言,一般情况下,我们在Objective-C中定义一个类时,总要提供一个初始化方法,一般大家都是这样写的:
这样一段简单的代码,却有很多可以思考的问题:
1、为什么要通过[superinit]来调用父类的初始化方法,父类的初始化方法里又执行了什么东西?
首先,我们知道对象继承的概念,一个子类从父类继承,那么也要实现父类的所有功能,这就是is-a的关系,比如说狗是哺乳动物,那么狗必定具有哺乳动物的特征和功能。所以在子类的初始化方法中,必须首先调用父类的初始化方法,以实现父类相关资源的初始化。例如我们在初始化狗这一对象时,必须先初始化哺乳动物这一对象,并把结果赋予狗,以使狗满足属于哺乳动物这一特征。
典型的,在iOS下,所有的类都继承于NSObject,而NSObject的init方法很简单,就是returnself。当父类的初始化完成之后,即self不为nil的情况下,就可以开始做子类的初始化了。
2、是否一定要提供初始化方法,是否一定要使用init作为初始化方法?
我们在Objective-C中创建一个对象通常使用
或者
new方法是NSObject对象的一个静态方法,根据apple的文档,该方法实际上就是alloc和init方法的组合,实际上二者是一样的,但apple还是推荐我们使用第一种方法,为什么呢?因为使用第一种方法,你可以使用自己定义的init方法来做一些初始化,当然,如果子类没有提供init方法,自然调用的就是父类的init方法了。所以说,从安全性的角度来收,作为开发者我们在对象使用之前是一定要对对象进行初始化的,因此在定义类的时候一定要提供初始化方法。但是否一定要使用init作为方法名呢?答案是不一定。使用init作为方法名只是你重写了NSObject的init方法而已,如果你自己重新定义一个初始化方法,也是完全可以的,只要你在使用的时候记得调用新定义的初始化方法就可以了。
但是,这种方法从设计角度来看我觉得是不可取的。在可复用性方面会比较差,如果确有必要定义一些接受不同参数的初始化方法,我的建议是,先定义一个init的公用方法,再到其他方法中调用它,如:
补充:
在面向对象编程中,如果编写一个类而没有包含构造函数,这个类仍能编译并且完全可以正常使用。如果类没有提供显式的构造函数,编译器会提供一个默认的构造函数给你。除了创建对象本身,默认构造函数的唯一工作就是调用其超类的构造函数。在很多情况下,这个超类是语言框架的一部分,如java中的Object类,objective-c中的NSObject类。
不论是何种情况,在类中至少包含一个构造函数是一种很好的编程实践,如果类中有属性,好的实践往往是初始化这些属性。
——以上摘自《TheObject-OrientedThoughtProcess》byMattWeisfeld
1 | -(MyClass*)init |
2 | { |
3 | self=[superinit]; |
4 | if (self){ |
5 | //执行一些资源、变量的初始化工作 |
6 | } |
7 | return self; |
8 | } |
1、为什么要通过[superinit]来调用父类的初始化方法,父类的初始化方法里又执行了什么东西?
首先,我们知道对象继承的概念,一个子类从父类继承,那么也要实现父类的所有功能,这就是is-a的关系,比如说狗是哺乳动物,那么狗必定具有哺乳动物的特征和功能。所以在子类的初始化方法中,必须首先调用父类的初始化方法,以实现父类相关资源的初始化。例如我们在初始化狗这一对象时,必须先初始化哺乳动物这一对象,并把结果赋予狗,以使狗满足属于哺乳动物这一特征。
典型的,在iOS下,所有的类都继承于NSObject,而NSObject的init方法很简单,就是returnself。当父类的初始化完成之后,即self不为nil的情况下,就可以开始做子类的初始化了。
2、是否一定要提供初始化方法,是否一定要使用init作为初始化方法?
我们在Objective-C中创建一个对象通常使用
1 | MyClass*newclass=[[MyClassalloc]init]; |
1 | MyClass*newclass=[Myclass new ]; |
但是,这种方法从设计角度来看我觉得是不可取的。在可复用性方面会比较差,如果确有必要定义一些接受不同参数的初始化方法,我的建议是,先定义一个init的公用方法,再到其他方法中调用它,如:
01 | -(id)init |
02 | { |
03 | self=[superinit]; |
04 | if (self){ |
05 |
06 | } |
07 | return self; |
08 | } |
09 |
10 | -(id)initWithString:(NSString*)aString |
11 | { |
12 | [selfinit]; |
13 | self.name=aString; |
14 | } |
15 |
16 | -(id)initWithImage:(UIImage*)aImage |
17 | { |
18 | [selfinit]; |
19 | self.image=aImage; |
20 | } |
在面向对象编程中,如果编写一个类而没有包含构造函数,这个类仍能编译并且完全可以正常使用。如果类没有提供显式的构造函数,编译器会提供一个默认的构造函数给你。除了创建对象本身,默认构造函数的唯一工作就是调用其超类的构造函数。在很多情况下,这个超类是语言框架的一部分,如java中的Object类,objective-c中的NSObject类。
不论是何种情况,在类中至少包含一个构造函数是一种很好的编程实践,如果类中有属性,好的实践往往是初始化这些属性。
——以上摘自《TheObject-OrientedThoughtProcess》byMattWeisfeld
相关文章推荐
- 浅谈 Objective-C 下对象的初始化
- 浅谈 Objective-C 下对象的初始化
- 浅谈 Objective-C 下对象的初始化
- 浅谈Objective-C对象初始化的三类程序猿
- 浅谈 Objective-C 下对象的初始化
- 浅谈 Objective-C 下对象的初始化
- Objective- c浅谈对象的初始化
- 浅谈 Objective-C 下对象的初始化
- 浅谈 Objective-C 下对象的初始化
- Objective-C 学习笔记 - part 3 - 为对象分配内存并初始化
- 浅谈 java对象的初始化【2012年7月25日 小冬分享】
- 浅谈OC对象初始化的三种姿势
- Objective-C 2.0 with Cocoa Foundation---对象的初始化以及实例变量的作用域(3)
- Objective-C 2.0 with Cocoa Foundation--- 7,对象的初始化以及实例变量的作用域
- Objective-C基础学习笔记——对象初始化
- JAVA--浅谈实例化对象时的初始化顺序
- Objective-C初学: 对象的初始化
- 【Objective-C基础】对象初始化
- objective-c中的构造函数(对象初始化)(七)
- Objective-C对象初始化