1.两种不同的创建对象的方法
1)[类名 new];
2)[[类名 alloc] init];
这两种方法是等价的。不过Cocoa惯例是使用alloc和init,而不是用new。因为alloc和init更能表现创建对象的实质,即分配内存和初始化对象。
2.编写初始化方法
-(id)init
{
if(self = [super init])
{
//执行一些资源、变量初始化操作
}
return self;
}
关于这段代码的思考:
1)为什么要通过[super init]来调用父类的初始化方法,父类的初始化方法里执行了什么?
[super init]的作用是:让超类完成其自身的初始化工作,在iOS下,所有的类都继承自NSObject类,而NSObject的init方法很简单,就是return self。当父类的初始化工作完成以后,即self不为nil的情况下,就可以进行子类的初始化了。
2)是否一定要提供初始化方法,是否一定要使用init作为初始化方法?
我们在Objective-C中创建一个对象通常使用
MyClass *newclass = [[MyClass alloc] init];
或者
MyClass *newclass = [Myclass new];
new方法是NSObject对象的一个静态方法,根据apple的文档,该方法实际上就是alloc和init方法的组合,实际上二者是一样的。但 apple还是推荐我们使用第一种方法,为什么呢?因为使用第一种方法,你可以使用自己定义的init方法来做一些初始化,当然,如果子类没有提供 init方法,自然调用的就是父类的init方法了。所以说,从安全性的角度来收,作为开发者我们在对象使用之前是一定要对对象进行初始化的,因此在定义类的时候一定要提供初始化方法。
但是否一定要使用init作为方法名呢?答案是不一定。使用init作为方法名只是你重写了NSObject的init方法而已,如果你自己重新定义一个初始化方法,也是完全可以的,只要你在使用的时候记得调用新定义的初始化方法就可以了。
但是,这种方法从设计角度来看我觉得是不可取的。在可复用性方面会比较差,如果确有必要定义一些接受不同参数的初始化方法,建议先定义一个init的公用方法,再到其他方法中调用它,如:
-(id)init
{
slef = [super init];
if(self)
{
}
return self;
}
-(id)initWithString:(NSString *)aString
{
[self init];
self.name = aString;
}
-(id)initWithImage:(UIImage *)aImage
{
[self init];
slef.image = aImage;
}
3.补充
在面向对象编程中,如果编写一个类而没有包含构造函数,这个类仍能编译并且完全可以正常使用。如果类没有提供显式的构造函数,编译器会提供一个默认的构造函数给你。除了创建对象本身,默认构造函数的唯一工作就是调用其超类的构造函数。在很多情况下,这个超类是语言框架的一部分,如java中的 Object类,objective-c 中的NSObject类。
不论是何种情况,在类中至少包含一个构造函数是一种很好的编程实践,如果类中有属性,好的实践往往是初始化这些属性。
——以上摘自《The Object-Oriented Thought Process》 by Matt Weisfeld