手动内存管理,主要需要注意2个问题,一个是空指针,另外一个是内存泄露,在开发当中,该如何去避免这样的问题.
首先还是要遵守内存管理原则(配对原则):只要出现了 new,alloc,retain,就一定配对出现一个release,autorelease
通过代码进行说明:
#import <Foundation/Foundation.h>
#import "Person.h"
void test()//空指针类型
{
//初始化对象,当前的引用计数器数量为1
Person * p = [[Person alloc] init];
p.age = 10;
NSLog(@"%@",p);
//执行release操作,对象P的引用计数器减为0,执行Person-->dealloc方法,p被销毁
[p release];
//这个时候,对象p已经在内存中被销毁,已经不存在,再通过该对象去调用该类说持有的方法,会引起程序崩溃,这就是一个空指针类型
[p run];
}
void test2()//针对上面这种空指针情况的处理
{
Person * p = [[Person alloc] init];//创建一个p对象
p.age = 20;//执行p的age属性的set方法
NSLog(@"%@",p);
//对p的引用计数器减1
[p release];
//如果确定当前作用域中的对象已经不会再被使用了,为了防止空指针操作,通常我们会把不在使用的指针变量赋值为nil
p = nil;
p.age = 30;//[nil setAge:30];
[p run]; //[nil run];
//避免野指针操作的方法 [nil resele]
//通过这种方法,可以让在运行时保证程序不会崩溃
}
void test3()//内存泄漏
{
//当前对象p的引用计数器值为1
Person * p = [[Person alloc] init];
p.age = 20;
NSLog(@"%@",p);
//执行retain操作,引用计数器值+1,当前retainCount值为2
[p retain];
//执行retain操作,引用计数器值+1,当前retainCount值为3
[p retain];
//执行release操作,引用计数器值-1,当前retainCount值为2
[p release];
//只要对象的retainCount != 0 就会一直存在在内存中
//内存泄漏指的就是,不再被使用的对象,一直在内存中没有被销毁
*/
#if 0
//内存泄漏另外一种情况
//retainCount = 1
Person * p = [[Person alloc] init];
p.age = 20;
[p run];
p = nil;
[p release];//这种情况同样会导致内存泄露,等同于[nil release]
#endif
#if 0
Person * p = [[Person alloc] init];
p.age = 20;
[p run];
Person * p1 = p;//将p所持有的对象让p1也持有,但是不让不执行retain操作,这是p1和p说持有的对象的计数器为1
// [p release];
[p1 release];
//当通过p或者p1对该对象进行一次release操作的时候,该对象的引用计数器减为0 ,对象销毁,p和p1不再指向任何的对象
//空指针操作
p1.age = 20;
#end if
}
void test4()
{
Person * p = [[Person alloc] init];
p.age = 20;
NSLog(@"%@",p);
[p release];
//空指针操作,当一个对象retainCount已经为0 时,调用retain方法,是不会使得对象起死回生的,同时还会发生野指针操作异常
[p retain];
}
void test5(Person * p)
{
p.age = 30;// release retain
[p retain]; //2
// [p release];
NSLog(@"%@",p);
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
//1
Person * p = [[Person alloc] init];
p.age = 20;
//将对象作为参数传递到方法里面,参数的引用计数器值不变
test5(p);
//1
[p release];
//0
//[p release];
}
return 0;
}
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property int age;
- (void)run;
@end
#import "Person.h"
@implementation Person
- (void)dealloc
{
[super dealloc];
NSLog(@"Person 被销毁了");
}
- (NSString *)description
{
return [NSString stringWithFormat:@"age = %d",_age];
}
- (void)run
{
NSLog(@"人跑起来了");
}
@end