一、object c内存管理总结1:object-c为每个对象提供一个内部计数器,这个计数器跟踪对象的引用次数。所有类都继承自NSObject对象的retain和release方法。
2:浅复制:只复制指针,两个对象拥有同一地址
深复制:重新创建一个对象,原有对象的成员变量的状态也复制过去
3:当对象在多个类中传递时,谁alloc或init或retain,谁就需要release它。在A中实例化,就需要在A丽release,
4:当对象被创建或者拷贝时,引用计数为1.每次保持对象时,就发送retain消息,使对象加1,调用release使其引用计数减1.
把对象传递到其他的类中时,需要retain下,防止在原来的类中被release。
当没有使用alloc来创建对象时就不需要手动release,例如:
NSString *str= [NSString stringWithString:@"duan"];
5:重写dealloc方法,就是为了释放对象里的成员变量;当对象的引用计数变量为0时,调用dealloc方法。在手动调用dealloc前,首先要做的是释放成员变量。
-(void) dealloc {
NSLog(@"释放Song对象...");
[title release]; //先释放成员变量
[artist release];
[super dealloc];
}
二、自动释放池
NSAutoreleasepool * pool=[[NSAutoreleasepool alloc] init];
[pool release];
autorelease不会马上减1,对象的引用计数并不真正变化,而是想内存释放池添加一条记录,记录下对象的这种要求,知道当内存释放池发送drain或release消息时,
三、创建对象的两个方法(构造方法)
以+和类名开头(去掉NS,小写第一个字母,array),就是类级构造方法,
NSString *myString = [NSString stringWithUTF8String:"my string"; //自动释放对象,这种方式实例化的对象是临时对象
以-和initWith开头的就是实例构造方法
类级构造方法不能使用release,可以不用autorelease就可以以自动纳入内存释放池管理
NSString *myString = [[NSString alloc] initWithUTF8String:"my string"; //这种实例化方法,对象会被保留,使用完毕后,必须手动进行释放
实例构造方法,如果发出release消息就马上释放对象,如果发出autorelease消息可以自动纳入内存释放池管理,不会马上释放。
在ios开发中,由于内存相对小,因此基本上都是采用实例构造方法实例化对象,采用发送release消息立刻释放对象内存。
类级构造方法(创建一个对象,创建同时初始化);其特点时方法名以NSArray去点NS并小写首字母开始,arrayWithObject。已
NSArray *weekName1 =[NSArray arrayWithObjects:@“星期一”,nil];
实例构造函数(初始化一个对象),必须手动release
NSArray *weekName=[[NSArray alloc] initWithObjects:@"星期一",nil];
四、属性中的内存管理参数:代替get和set方法。对get,set的控制 readonly 、readwrite,非原子性nonatomic,内存管理的:retain、copy、assign
属性参数--三类 6个参数:内存管理3个,线程管理1个,读写2个
内存管理的三个参数retain、copy、assign
问题:
-(void) setTitle:(NSString *) newTitle
{
title=newTitle; //把title的指针换掉了,title并没有释放,如果多次调用该方法,内存会不断增加,
}
解决方法:
-(void) setTitle:(NSString *) newTitle
{
[newTitle retain]; //防止在计算过程中将其释放
[title release]; //释放原来的内存
title = [[NSString alloc] initWithString]: newTitle]; //重新分配内存
[newTitle release];
}
1、assign参数表示设置时直接赋值,而不是复制或保留它。这种类型非常适合一些基本类型,比如NSInteger和CGFloat,或者就是不想直接拥有的类型,比如委托。
assign相当于如下用法:
-(void) setTitle:(NSInteger *) newTitle
{
title=newTitle; //把title的指针换掉了,title并没有释放,如果多次调用该方法,内存会不断增加,
}
retain相当于如下用法:
-(void) setTitle:(NSString *) newTitle
{
[newTitle retain]; //防止在计算过程中将其释放
[title release]; //释放原来的内存
title = [[NSString alloc] initWithString]: newTitle]; //重新分配内存
[newTitle release];
}
3、copy在赋值时将新值拷贝一份,拷贝工作由copy方法执行,此属性只对那些实现了NSCopying协议的对象类型有效。
copy相当于如下用法:
-(void) setTitle:(NSString *) newTitle
{
[newTitle copy]; //相当于一个副本
[title release]; //释放原来的内存
title = [[NSString alloc] initWithString]: newTitle]; //重新分配内存
[newTitle release];
}