内存管理常见错误
没有改为自动管理内存
解决方法:
野指针问题
[Person retainCount]: message sent to deallocated instance 0x1002032d0 消息发送给一个已经回收的对象
野指针异常现象:可能会崩溃,也可能不会崩溃,写到某一行代码时突然崩溃(没有写任何和引用计数相关的代码)原因:该对象的空间,已经被系统回收,不能访问没有所有权的对象解决方案:空间被系统回收之后,禁止访问
或者令其指向无效空间
过度释放
过度释放现象:当调用内存引用计数减一有关的操作后,程序立即崩溃.原因:空间被系统回收之后,不能再做和引用计数减一有关的操作,否则会立即崩溃解决方案:删除多余释放语句
当引用计数为零时,系统会自动回收内存,我们只管理引用计数
@autoreleasepool的使用原则 @autoreleasepool { Person *person
= [[Person alloc] init];//0-1
[person retain];//1-2 NSLog(@"%ld",
[person retainCount]); @autoreleasepool {
[person autorelease];//2-1 }autorelease,会将声明为autorelease的对象放入离他最近的自动释放池中,当自动释放池销毁时,会向池中的每一个对象,发送一个release消息
当该类型的对象引用计数为零时,系统会自动调用该类的dealloc方法来回收空间,该方法是由系统自动调用,不能手动调用验证对象,空间有没有没回收,只要查看该类的dealloc方法有没有执行即可,如下-
(void)dealloc{ NSLog(@"dealloc,你完蛋了,空间回收了");
[super dealloc]; }
内存管理基本原则:如果你对一个对象进行alloc retain copy之后,你就具有了该对象的所有权,你就必须对它进行release或者autorelease.(只要调用了alloc
retain copy,就进行release 或
者autorelease)
内存管理典型例子
1. 在一个对象的方法里面:假设name的语义特性为retain
self.name = [[NSString alloc] initWithFormat:@“object”];
和
_name =[[NSString alloc] initWithFormat:@“object”];
有什么不同吗?
self.name,是先给name赋值,会调用setter方法,setter方法内部进行了引用计数 + 1操作,因此它的引用计数为2
_name只是简单的赋值操作,因此引用计数不发生改变
2. - (void)setPeople:(NSString *)p{
self.people = p;
}
这段代码有什么问题。
会出现死循环,self.people会调用自己的setter,而self.people还处于setter方法内部,因此会出现死循环
3.有一个NSStirng类型,retain方式声明的name属性的setter方法内部每一行代码的作用?
- (void)setName:(NSString *)name {
判断原有对象和新对象是否是同一个对象,如果是同一个,就没有必要再重新赋值,否则会先release
再retain,就会变成野指针
if (_name != name) {
释放保有之前对象的所有权 [_name
release];
让实例变量 _name保有新的对象的所有权
_name = [name
retain]; } }