首页 > 代码库 > 内存管理的常见错误

内存管理的常见错误

内存管理常见错误

没有改为自动管理内存


   
解决方法:




野指针问题



[Person retainCount]: message sent to deallocated instance 0x1002032d0 消息发送给一个已经回收的对象
野指针异常现象:可能会崩溃,也可能不会崩溃,写到某一行代码时突然崩溃(没有写任何和引用计数相关的代码)原因:该对象的空间,已经被系统回收,不能访问没有所有权的对象解决方案:空间被系统回收之后,禁止访问  或者令其指向无效空间


过度释放



过度释放现象:当调用内存引用计数减一有关的操作后,程序立即崩溃.原因:空间被系统回收之后,不能再做和引用计数减一有关的操作,否则会立即崩溃解决方案:删除多余释放语句
当引用计数为零时,系统会自动回收内存,我们只管理引用计数

@autoreleasepool的使用原则     @autoreleasepool {        Person *person = [[Person allocinit];//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 {
       判断原有对象和新对象是否是同一个对象,如果是同一个,就没有必要再重新赋值,否则会先releaseretain,就会变成野指针
    if (_name != name) {       释放保有之前对象的所有权        [_namerelease];       让实例变量 _name保有新的对象的所有权       _name = [nameretain];    } }


内存管理的常见错误