前言: OC中定义和初始化对象一般使用alloc,不用new,原因:
new和alloc/init在功能上几乎是一致的,分配内存并完成初始化。
差别在于,采用new的方式只能采用默认的init方法完成初始化,
1. init继承于NSObject这个根类,所有的子类可以不用重写这个实例方法函数,当然也可以在自己的类里重写init实例方法
2. 可以自定义构造函数,一般以init开头
3. 初始化时类之间的协调,主要是继承时需要关注
一个类的init...方法中通常只对在该类中定义的变量进行初始化。对继承而来的实例变量的初始化是通过向super发送消息,调用在继承关系图中更高层的类的初始化方法来完成的:
- -(id)initWithName:(NSString *)string
- {
- self = [super init];
- if (self)
- {
- name =[string copy];
- }
-
- return self;
- }
通过向super发送消息可以把继承关系图中的所有相关类关联起来。由于是最先向super发送消息的,所以这种方式确保了超类的实例变量是在派生类的实例变量之前被初始化的。例如,Rectangle类的对象最先应该是作为NSObject类的对象来进行初始化,然后是Graphic类的对象,再次是Shape类的对象,最后才是Rectangle类的对象。
之前程序段中的initWithName:和继承而来的init方法的之间的关系如图3-1所示:
│
┌───────────────────────┐ │
│ -init │─────┘
│ │<────┐
class A │ │ │
│ │ │
│ │ │
└───────────────────────┘ │
│
│
│
┌───────────────────────┐ │
│ -initWithName: │─────┘
│ │
class B │ │
│ │
│ │
└───────────────────────┘
图3-1
如上图中,由于A中定义了init方法,作为A类的派生类B继承了该init方法。但是由于A中的init方法只是对定义在A中的实例变量进行了初始化,因此继承而来的init方法不能对B类中的实例变量进行初始化,因此B中必须重写init方法,以便B类的init方法即能完成对继承而来实例变量的初始化也能完成对自身中定义的实例变量的初始化。:
- - init
- {
- return [self initWithName:"default"];
- }
而在initWithName:方法中调用了继承而来的init方法,A类和B类初始化的关系变成如图3-2所示:
│
┌───────────────────────┐ │
│ -init │─────┘
│ │<────┐
class A │ │ │
│ │ │
│ │ │
└───────────────────────┘ │
│
│
│
┌───────────────────────┐ │
┌───│ -init │ │
│ │ │ │
class B └──>│ -initWithName: │─────┘
│ │
│ │
└───────────────────────┘
图3-2
这样做会使得自己的程序更具有兼容性。如果没有对这样的继承而来的方法进行重写,可能会导致别人使用了没有被正确初始化的对象。
二、析构函数
析构函数声明为“-(void)dealloc”这个函数我们不能通过对象去人为的调用它,析构函数会在对像快要死的时候自己运行,来看代码。
1 @interface Person:NSObject{
2 @private
3 int age;
4 NSString *name;
5 }
6 -(void)dealloc; //声明析构函数,析构函数只能有一个
7 @end
8
9
10 @implementation Person //实现Person 类
11 -(void)dealloc{
12 NSLog(@"this is dealloc function");
13 [super dealloc];
14 }
15
16 @end
17
18 Person *xiaoming = [Person alloc];
19 [xiaoming release];
在代码的第六行我们声明了析构函数,并且在第11行处我们对其进行了复写,这个函数会在执行[xiaoming release];的时候运行,因为release函数就是销毁对象。
注意:有时候我们复写dealloc函数的时候加上[super dealloc];会出现错误![](http://images0.cnblogs.com/blog2015/758526/201506/011040524416332.png)
这是因为ARC是iOS 5推出的新功能,全称叫 ARC(Automatic ReferenceCounting)。简单地说,就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。该机制在iOS 5/ Mac OS X 10.7 开始导入,利用 Xcode4.2可以使用该机制。简单地理解ARC,就是通过指定的语法,让编译器(LLVM3.0)在编译代码时,自动生成实例的引用计数管理部分代码。有一点,ARC并不是GC,它只是一种代码静态分析(StaticAnalyzer)工具。
解决办法:双击中间的工程名称,进入build setting
![](http://images0.cnblogs.com/blog2015/758526/201506/011043318327292.png)
将中间的Objective-C Automatic Reference Counting改为no就OK了!
参考:
1.
http://blog.csdn.net/zhangxingping/article/details/7177532
2.
http://www.cnblogs.com/ITLiu/p/4543439.html?utm_source=tuicool&utm_medium=referral