——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
概念:
MRC:MannulReference Counting ( 手动管理 )
对引用计数器的操作 :
retain消息:使计数器+1,该方法返回对象本身
release消息:使计数器-1(并不代表释放对象)
retainCount消息:获得对象当前的引用计数器值
当一个对象的引用计数器为0时,那么它将被销毁,其占用的内存被系统回收。
当对象被销毁时,系统会自动向对象发送一条dealloc消息,一般会重写dealloc方法,在这里释放相关的资源,dealloc就像是对象的“临终遗言”。
一旦重写了dealloc方法就必须调用[super dealloc],并且放在代码块的最后调用(不能直接调用dealloc方法)。
Person.h声明:
<span style="font-size:24px;">#import <Foundation/Foundation.h>
@interface Person : NSObject
@property int age;
@end</span>
Person.m实现:
<span style="font-size:24px;">#import "Person.h"
@implementation Person
//重写dealloc方法
-(void)dealloc{
//释放子类对象
NSLog(@"对象被销毁了~");
//释放父类
[super dealloc];
}
@end</span>
<span style="font-size:24px;">#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
Person *p = [[Person alloc] init];
NSLog(@"p的retainCount = %ld",p.retainCount);
Person *p1 = [[Person alloc] init];
NSLog(@"p1的retainCount = %ld",p1.retainCount);
[p1 retain];
NSLog(@"p1的retainCount = %ld",p1.retainCount);
[p1 release];
NSLog(@"p1的retainCount = %ld",p1.retainCount);
[p1 release]; //此时p还没释放,造成内存泄露了
return 0;
}</span>
p1的retainCount = 1
p1的retainCount = 2
p1的retainCount = 1
对象被销毁了~
实例分析:凤姐去拉萨多对象处理
Person.h声明:
<span style="font-size:24px;">#import <Foundation/Foundation.h>
#import "Car.h"
@interface Person : NSObject{
Car *_car;
}
-(void)dealloc;
-(void)goLasa;
-(void)setCar:(Car *)car;
@end</span>
Person.m的实现:
<span style="font-size:24px;">#import "Person.h"
@implementation Person
-(void)dealloc{
[_car release]; //在人对象释放前,先释放掉车的对象
NSLog(@"人已经挂了!");
[super dealloc];
}
-(void)goLasa{
[_car run]; //插入车的跑方法
}
/*此处会有一个新的问题:
如果此时并未出现新的对象,而是旧的对象,如果没有判断的话
此时旧的对象会变成僵尸对象,程序则会出错。
*/
-(void)setCar:(Car *)car{
if(_car != car){
[_car release]; //为了防止车的多对象产生内存泄露,在retain之
// 前释放掉当前对象
_car = [car retain]; //给人的对象设置车时,再次增加一次车的retain
}
}
@end</span>
Car.h声明:
<span style="font-size:24px;">#import <Foundation/Foundation.h>
@interface Car : NSObject/*{
int _speed;
}*/
@property int speed;
-(void)dealloc;
//-(int)setSpeed:(int)speed;
//-(void)getSpeed;
-(void)run;
@end</span>
Car.m的实现:
<span style="font-size:24px;">#import "Car.h"
@implementation Car
-(void)dealloc{
NSLog(@"速度为 %d 码的车已经挂了",_speed);
[super dealloc];
}
/*-(int)setSpeed:(int)speed{
_speed = speed;
return speed;
}
-(void)getSpeed{
}*/
-(void)run{
NSLog(@"汽车正以%d码的速度奔向拉萨",_speed);
}
@end</span>
main.m主函数:
<span style="font-size:24px;">#import <Foundation/Foundation.h>
#import "Car.h"
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *fj = [Person new];//此时fj的retainCount就变成了1;
Car *bmw = [Car new];//此时bmw的retainCount就变成了1;
[fj setCar:bmw];
// [bmw setSpeed:100];
bmw.speed = 200;
[fj goLasa];//在setCar中插入了[_car retain]
[fj goLasa];//此时bmw的retainCount就变成了2;
[fj goLasa];
NSLog(@"retainCount = %lu",bmw.retainCount);
[bmw release];//内存管理原则,谁创建谁release
Car *qq = [Car new];
[fj setCar:qq];
[qq setSpeed:20];
// NSLog(@"retainCount = %lu",bmw.retainCount);
[fj goLasa];
[fj goLasa];
[fj goLasa];
[qq release];
[fj release];//内存管理原则,谁创建谁release
// NSLog(@"retainCount = %lu",bmw.retainCount);
}
return 0;
}</span>
运行结果: 汽车正以 200 码的速度奔向拉萨
汽车正以200码的速度奔向拉萨
汽车正以200码的速度奔向拉萨
retainCount = 2
速度为 200 码的车已经挂了
汽车正以20码的速度奔向拉萨
汽车正以20码的速度奔向拉萨
汽车正以20码的速度奔向拉萨
速度为 20 码的车已经挂了
人已经挂了!