/——————————————————————————————/
OC内存管理
/————————————————————————————/
当A、B、C都要使用obj时,要共用一个obj对象节省内存空间,而不是创建3个obj,此时就要管理内存。
系统销毁obj对象时,会判断obj是否正在被使用,obj的内存空间被引用了就表示此对象还在使用,此时系统不会销毁obj,(没有人使用obj的时候还没有销毁,就造成了内存泄露),对多少个其他对象引用了obj进行统计就是引用计数。
OC的内存管理机制就是引用计数管理。
——————————————————
内存管理方法:
obj创建者用alloc创建内存空间存放obj,不用的时候release。
其他对象用obj时先retain,告诉系统自己正在使用,不用的时候release,告诉系统不使用了
——(不retain的后果是:如果obj创建者release之后,obj被系统销毁,你的引用就会变成野指针)
谁用obj 谁release,release之后要把指向obj的指针=nil
——————————————————
A对象:
NSString *str = [[NSString alloc] initWithString:@"HELLO"]; //alloc一块内存空间存放str,retainCount =1
[B useStr:str]; //B对象使用str,B会先retain再release
/*
A使用完后release
*/
[str release];
str = nil;
B对象:
NSString * s = [str retain]; //引用计数+1(retain声明使用str)
//NSString *s = [str copy]; //copy是复制了一个新的对象,你也需要release
NSLog(@"%lu", s.retainCount); //查看引用计数
[s release]; //引用计数-1(release声明不使用str了)
[str release]; //与上一句一样的效果
s = nil; //指针置空
/*
nil给oc数据类型指针置空
NULL给c数据类型指针置空
*/
————————————————————————————————
// setter方法是这样写的
-(void)setName:(NSString *)name {
if(_name != name) {
[_name release]; //释放_name的内存空间
_name = [name retain]; //把_name指向name,并retain告诉系统我正在使用
}
}
————————————————————————————————
在dealloc中对自身的成员变量进行销毁
————self.arr是执行的操作:[self setArr:nil]; 是调用setArr方法
*注意*:不是self的成员变量不能nil,没有实现setter方法不能用
————————————————————————————————
例子1:
-(id)initWithName:(NSString *)name andPassword:(NSString *)password {
self = [super init];
if (self) {
//土豪行为,使用了2快空间,创建一块NSString空间,并赋值为name
// _name = [[NSString alloc] initWithString:name];
// _password = [[NSString alloc] initWithString:password];
/*
应该这样子:
指针指向name(节省内存),并retain告诉系统我正在用
*/
_name = [name retain];
_password = [password retain];
}
return self;
}
// 有alloc、retain就应该有release,有init就应该有dealloc
- (void)dealloc
{
/*
release告诉系统我用完了
*/
[_name release];
[_password release];
[super dealloc];
}