黑马程序员技术交流社区

标题: 单个对象的内存管理 [打印本页]

作者: liminghui    时间: 2015-9-17 18:57
标题: 单个对象的内存管理
内存管理的原则 :
            1:如果对象有人在使用,那么就不应该回收。如果你想使用这个对象,就应该让这个对象retain一次。如果你                     不想用这个对象了,就应该让这个对象release一次。
            2:谁创建 谁release (哪个对象创建了空间,那个对象就release)
            3:谁retain 谁release (哪个对象的空间引用计数器retain了,哪个对象就release)
内存管理研究的内容:
             1:野指针:定义的指针变量没有初始化或者是指向的空间已经被释放。
             2:内存泄露:如果栈区的指针变量已经被释放了,而堆区的空间还没有释放,堆区的空间就被泄露。
单个对象的内存管理(野指针):
              1:野指针错误:访问了一块坏的内存(已经被回收的不可用的内存)。
              2:僵尸对象:所占内存已经被回收的对象,  僵尸对象不能再被使用。
              3:空指针:对象值为空,没有指向任何东西的指针,给空指针发送消息不会报错。
                   nil: 表示对象的值
                   NIL:表示类的值
                   NULL:通用指针(泛型指针)
                  [NSNull null]: 是一个对象,他用在不能使用nil的场合             (了解即可)
               4: 当一个对象的空间被释放了,引用计数器为0,这个对象是僵尸对象,如果再用[对象名  retain]方法是不行的。下面举个例子:
如: Dog *d = [Dog new];     //创建一个对象,他有一个拥有者,引用计数器的值为1
                 [d release];               //用release方法使计数器减1, 这时的计数器为0,对象的空间被释放。
                 [d  retain];               //对象空间已被释放,对象成为了僵尸对象,这时再retain是不合法的。
如果非要对已释放空间的对象retain,那么看下面的方法 :
如: Dog *d = [Dog new];     //创建一个对象,他有一个拥有者,引用计数器的值为1
                 [d release];               //用release方法使计数器减1, 这时的计数器为0,对象的空间被释放。
                 d = nil;                   // 在上一步对象空间被释放,这时的对象d指向了nil,也就是0,所以下面的retain可以执行
                 [d  retain];        //上一步对象d指向了nil(0),计数器为0,对象有指向不是僵尸对象,多以可以执行这步。
单个对象的内存泄露问题:
    情况1:
                  //  对象创建完成开辟完内存空间后没有release,计数器为1,程序结束后内存还存在没释放
            Dog *d = [[Dog alloc] init ];
              return 0;
    情况2:
               //  没有遵守内存管理的原则
Dog *d = [[Dog alloc] init ];           //创建对象   计数器为1
              [d retain];                                        //  retain(+1)   计数器为2
              [d  release];                                   // release (-1)   计数器为1
              return 0;                                     //程序结束时  计数器不为0,内存空间没有释放
     情况3:
               //  不当的使用了nil
Dog *d = [[Dog alloc] init ];           //创建对象   计数器为1
               d = nil;                                              // 把0赋值给了对象d,下面方法不会执行
              [d  release];                                   //  这一步就相当于  [nil  release]
              return 0;                                     //程序结束时  计数器不为0,内存空间没有释放
       情况4:
               // 在方法中对传入的对象进行了retain
  前提:     -(void)run{
                             [d retain]             //run方法中retain了一次对象d
                                             }
   后续:        Dog *d = [[Dog alloc] init ];           //创建对象   计数器为1
                              [d run] ;           //对象d调用方法run    因为run方法中又给对象retain一次  所以计数器为2
[d  release];     // 计数器为2,这步只release了一次,计数器为1 内存没被释放。


作者: zhaopengfei    时间: 2015-9-17 21:16
我很想告诉你 我不知奥




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2