(一)Xcode设置:
6.x版本Xcode是自动打开acr并且不报错僵尸对象的。更改方式为首先新建好Project,在工程Bulid SEttings下面的搜索
功能中输入关键字arc,再在下方的Apple LLVM 6.0-Language--ObjectiveC中的ObjectiveC Automatic Reference
Counting功能中选择NO。之后在运行按钮(左上方小箭头)边上的Edit scheme选项的run中勾选Enable Zombie
Objects按钮。至此环境勾选好,我们才能测试接下来的内存管理代码。
(二)多对象内存管理:
IOS对象间肯定是多个对象有着千丝万缕的联系的。什么时候删除这个对象,什么时候计数器增加这些问题都对我们的
性能起着很大的作用。一般来说,有加必有减,谁加的谁减少,对象调用完毕后计数器最终都会变为0。当一个类碰到
alloc,new时,表示这个对象刚刚创建,此时计数器加1,然后应该写一个相应的release方法与之相对应。当一个对象
碰到了retain方法使计数器加1,也要有相应的release与之相对应。在多对象中,对象之前往往是有关系的。为了在对
象互相使用中不会出错,规定一个对象A使用另一个对象B时,那么这个对象B计数器应该加1,加1表示有一个人在用,
只有所有人都不用了,计数器归零的时候,这个对象B才会从内存中移除。
综上所述。当一个类用到了另一个类的东西时(成员变量里面有另一个类属性,或者是NSString字符串类型),用set
方法赋值时候应该先判断当前类是否已经赋值了这个类,如果没有,就使当前类的旧属性release1,新属性retain1。并
且在这个类死亡时候(dealloc),会释放这个类占有的其他类属性,不再是使用或者拥有关系,此时应该是当前属性调
用release方法-1。所以要重写这个包含其他类信息的成员变量的set方法和当前类的dealloc方法达成目的。下面代码分
析一下书写规范。
假设学生类和狗类,学生拥有一条狗,此时重写学生的狗成员变量的set方法
<div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"><span style="font-size:18px;">- (void)setDog:(Dog *)dog</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">{</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> if (_dog =dog)</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> {</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> [_dog release];
</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> </span></span></div><div style="text-align: justify;"><span style="font-size:18px;"><span style="font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-family: Arial, Helvetica, sans-serif;"> [dog retain];</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> }</span></span></div><span style="font-size:18px;"></span><div style="text-align: justify;"></div><div style="text-align: justify;"></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">}</span></span></div>
如上,如果这是一条新狗,就让我的旧狗属性计数器-1(我不要你了),新狗计数器+1,并且赋值给我的当前狗属性。
下面重写一下学生对象的dealloc方法
<div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"><span style="font-size:18px;">- (void)dealloc{</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> [_dog release];</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> [super dealloc];</span></span></div><div style="text-align: justify;"></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">}</span></span></span></div>
总结内存管理代码规范:
①只要调用了alloc,new必须有release(autorelease)。
②重写set方法基本规范:
当成员变量为基本数据类型时,因为不涉及到内存泄露,所以不用重写set方法。
当成员变量为OC对象时,重写set方法防止内存泄露。
}
③delloc方法重写规范:
}
④内存泄露:
<span style="font-size:18px;"> Student *stu = [[Student alloc] init];</span>
<span style="font-size:18px;"> stu.dog = [[Dog alloc] init]; </span>
<span style="font-size:18px;">[[Dog alloc] init].speed = 40;</span>
分析:第一句创建了一个学生对象,并且由指针stu代表这个对象。第二句直接创建了一个狗对象通过set点语法赋值给
了stu的狗属性。狗对象刚创建出来时,alloc-->次数计数器为1,调用set方法赋值时,计数器为2.学生对象死亡
时,会release狗对象,此时狗对象计数器为1,狗对象已经没人指着它了,已经没有用了,但是还在内存中。造成了
内存的泄露。下面的一句代码道理依然如此。总体来说,还是有一个alloc就应该对应一个release,要不就会出错。
<span style="font-size:18px;">@property (retain,nonatomic,readwrite,setter=shy:) NSString *name;</span>
<div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">#import <Foundation/Foundation.h></span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">typedef enum {</span></span></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"> Sexman,</span></div><div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">f struct {</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;"> </span></div></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"> Sexwoman</span></div>} Sex;
<div style="text-align: justify;"></div>type
d
<div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">e int year;</span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"> int momth;</span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">ce User : NS</span></span></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"> int day;</span></div>} Date;
<div style="text-align: justify;"></div>@inter
f
<div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">aObject</span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">// 姓名,微博号码,密码,头像,性别,手机,生日</span></div><div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">ing *name;</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;">@property (nonatomic,retain) NSSt</span></div></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">@property (nonatomic,retain) NSSt</span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">rring *weibono;</span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">@property (nonatomic,retain) NSString *password;</span></div><div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">mic,assign) Sex sex;</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;">@property (nonatomic,retai</span></div></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">@property (nonatomic,retain) NSString *picture;</span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">@property (nonat</span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">on) NSString *phone;</span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">@property (nonatomic,assign) Date birthday;</span></div><div style="text-align: left;"></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">@end</span></div>
<div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">#import "User.h"</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">@implementation User</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">// 姓名,微博号码,密码,头像,性别,手机,生日</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">- (void)dealloc</span></span></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">{</span></div><div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">];</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;"> [_weibono rel</span></div></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"> [_name releas</span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">eease];</span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"> [_password release];</span></div><div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">ne release];</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;"> [super</span></div></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"> [_picture release];</span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"> [_ph</span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">o dealloc];</span></div>}
<div style="text-align: left;"></div><span style="font-size:18px;">@end</span>
<div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">#import <Foundation/Foundation.h></span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">#import "User.h"</span></span></div><div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">,微波发送人,转发的微波,被评论数,被转发数</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;">@interface WeiBo</span></div></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">// 微波内容,微波配图,发送时</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">间 : NSObject</span></span></div><div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">natomic,retain) NSString *neirong;</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;">@property (n</span></div></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">@property (n</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">oonatomic,retain) NSString *picture;</span></span></div><div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">ime;</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;">@property (nonatomic,retain) User *u</span></div></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">@property (nonatomic,assign) time_t </span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">tser;</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">@property (nonatomic,retain) WeiBo *weibo;</span></span></div><div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">ty (nonatomic,assign) int zhaunfa;</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;">@end</span></div></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">@property (nonatomic,assign) int pinglun;</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">@prope</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">r</span></span></div>
<div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">#import "WeiBo.h"</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">// 微波内容,微波配图,发送时间,微波发送人,转发的微波,被评论数,被转发数</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> [_neirong release</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">@implementation WeiBo</span></span></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">- (void)dealloc</span></div>{
];
<div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">;</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;"> [_weibo release];</span></div></div><span style="font-size:18px;"> [_picture release];
[_user release
]
[super dealloc];
}
@end
</span><div style="text-align: left;"></div>
<div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">#import <Foundation/Foundation.h></span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">#import "User.h"</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">#import "WeiBo.h"</span></span></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">int main()</span></div>{
<div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">er alloc] init];</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;"> u1</span></div></div><span style="font-size:18px;"> // 创建用户1,输入名字,账号,性别
User *u1 = [[U
s.name = @"梁萧";
u1.weibono = @"ksca00892002";
u1.sex = Sexman;
</span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">.nam</span></span></div><span style="font-size:18px;">
// 创建用户2,输入名字,账号,性别
User *u2 = [[User alloc] init];
u
2e = @"花花";
u2.weibono = @"kstg3171525";
u2.sex = Sexwoman;
</span><div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">w1.neirong = @"黑马训练营";</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;"> w1.u</span></div></div><span style="font-size:18px;"> // 创建微博1,输入微博内容,并且微博发送者是用户1
WeiBo *w1 = [[WeiBo alloc] init];
ser = u1;
// 创建微博2,输入微博内容,并且微博发送者是用户2,然后转发微博1
WeiBo *w2 = [[WeiBo alloc] init];
</span><div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">lease</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"></span></span><div style="text-align: justify;"> [w2 release];</div><div style="text-align: justify;"> </div></div><span style="font-size:18px;"> w2.neirong = @"itcast";
w2.user = u2;
w2.weibo = w1;
// 一个alloc对应一个相对应的r
e [w1 release];
[u2 release];
[u1 release];
return 0;
</span><div style="text-align: left;"></div><span style="font-size:18px;">}</span>
autorelease是一个对象方法,可以代替release。autorelease方法调用完毕后,会返回对象本身。并且不会影响对象本身计数器的增减。代
码表示为:
<div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"><span style="font-size:18px;"> @autoreleasepool</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> {</span></span></div><div style="text-align: left;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">er *u = [[[User alloc] init] autorelease];</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;"> u</span></div></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> U</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">s.name = @"shy";</span></span></div><div style="text-align: left;"></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> }</span></span></span></div>
总结:
①自动释放池:
自动释放池可以创建无数多个并且可以嵌套使用。它是存放在栈中的,这个栈和我们之前说的数据类型存放在内存中的堆,栈中的栈是不一样
的。这个栈是一个存储方式。遵循先进后出得原则。先存进来的最后释放,第一个创建的autoreleasepool是最后释放的,而它里面嵌套的释放
池先释放。
②atuorelease基本用法:
- 会将对象放到自动释放池。
- 自动释放池在第二个大括号结束时销毁,此时对所有池子中的对象做一次release操作。
- autorelease是一个对象方法。返回对象本身。
- autorelease的调用不影响计数器增加减少。影响计数器增加减少的只有retain和release。
③autorelease好处:
- 不需要关系对象释放时间。不用在一个alloc对应一个release,并且时刻注意所有对对象的操作都必须在release前面。
- 占用内存较大的对象不要随便使用autorelease,autorelease只是延长了自动释放的时间,而不是自动销毁,但是无法精确的控制释放时间。所以开发时候一般使用release精确控制。
- 占用内存较小的可以使用autorelease,没有太大影响。
- 使用autorelease要需要有池子。并且每次调用都要放到栈顶。
- 一个alloc对应一个release或者autorelease,如果对应两个就会报错。
- 连续多次调用autorelease也不对,一次autorelease会做一次release,多次调用会出现野指针错误。
⑥高级使用方法:
autorelease一般可以进行封装。封装在类方法中方便创建。
<div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"><span style="font-size:18px;">+ (id)perdon</span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">{</span></span></div><div style="text-align: left;"></div><div style="text-align: justify;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> return [[[Perdon alloc] init] autorelease];</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"></span><div style="text-align: justify;"><span style="font-size:18px;">}</span></div></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> </span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> </span></span></div><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">+ (id)perdonWithAge:(int)age</span></span></div><span style="font-size:18px;"></span><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;">{</span></div>
<div style="text-align: justify;"><div style="text-align: justify;"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;">init] autorelease];</span></span></div><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:18px;"> p.age = age;
</span></span><div style="text-align: left;"></div> return p;
<div style="text-align: left;"></div>}
</div><span style="font-size:18px;"> Perdon *p = [[[Perdon alloc]
- (void)dealloc
{
NSLog(@"Perdon---要死掉了");
[super dealloc];
</span><div style="text-align: justify;"></div><span style="font-size:18px;">}</span></span>
- 当系统自带的方法里没有alloc,copy,new时,说明返回值对象都是autorelease类型的。
- 开发中经常会提供一些类方法,快速创建一个已经autorelease过的对象。创建对象时不要直接用类名,尽量用self。这样子类也能用。