黑马程序员技术交流社区

标题: 关于内存管理的问题 [打印本页]

作者: 为梦想挺身而出    时间: 2014-6-27 20:42
标题: 关于内存管理的问题
  1. Person *p1 = [[Person alloc] init];
  2.     Person *p2 = [[Person alloc] init];
  3.     Person *p3 = [[Person alloc] init];

  4.     [p1 release];
  5.     [p2 release];
  6.     [p3 release];

  7. 2014-06-27 20:37:19.058 小小测试[2828:303] 对象被回收了
  8. 2014-06-27 20:37:19.061 小小测试[2828:303] 对象被回收了
  9. 2014-06-27 20:37:19.063 小小测试[2828:303] 对象被回收了
复制代码

有alloc 有release 内存无泄漏
  1.     Person *p1 = [[Person alloc] init];
  2.     Person *p2 = [[Person alloc] init];
  3.     Person *p3 = [[Person alloc] init];
  4.    
  5.     NSArray *array = [NSArray
  6. arrayWithObjects:p1, p2, p3, nil];

  7.    
  8.     [p1 release];
  9.     [p2 release];
  10.     [p3 release];
  11. 这样就没有调用dealloc方法
复制代码

除非这样

  1. Person *p1 = [[Person alloc] init];
  2.     Person *p2 = [[Person alloc] init];
  3.     Person *p3 = [[Person alloc] init];
  4.     @autoreleasepool {
  5.    
  6.     NSArray *array = [NSArray arrayWithObjects:p1, p2, p3, nil];
  7.         
  8.     }
  9.     [p1 release];
  10.     [p2 release];
  11.     [p3 release];
复制代码


我的疑问是,如果不用@autorelease{} 怎么手动管理内存
作者: TLTY    时间: 2014-6-27 21:15
    Person *p1 = [[Person alloc] init];   / / p1的计数是1
    Person *p2 = [[Person alloc] init];   / /p2 的计数是1
    Person *p3 = [[Person alloc] init];   / /p3 的计数是1
    @autoreleasepool {
   
    NSArray *array = [NSArray arrayWithObjects:p1, p2, p3, nil];
        
    }    / /因为把三个对象都加到数组里了,故p1、p2、p3 的计数是都加了1,故他们的计数都是2了,最后虽然你对三个对象都用了release,也只是使他们的计数减了1,只有对象的计数是为0了,才先调用dealloc方法,然后释放内存
    [p1 release];
    [p2 release];
    [p3 release];

作者: chain    时间: 2014-6-27 23:23
本帖最后由 chain 于 2014-6-28 00:40 编辑

按道理来说静态方法应该是自动释放啊
作者: chain    时间: 2014-6-28 00:42
TLTY 发表于 2014-6-27 21:15
Person *p1 = [ init];   / / p1的计数是1
    Person *p2 = [ init];   / /p2 的计数是1
    Person * ...

你说的是有道理,但是数组释放的时候会对数组的所有元素做一次release操作啊,最后3次release是对应前面3个alloc啊
作者: Littlekin    时间: 2014-6-28 08:12
要想自己手动管理内存,就要用动态方法创建对象。视频中有讲过,跟创建person对象一样使用alloc和init方法,这样创建时retain计数器+1。如下:
NSArray *array =[[NSArray alloc] initWithObjects:p1, p2, p3,nil];
这样你就要手动释放内存了。
作者: 秋天的悲伤    时间: 2014-6-28 10:48
瞬间凌乱了,照理说应该是在NSArray释放的时候对person做一次release的,但你用的是初始化函数,所以不知道在什么时候释放了,你用的autoreleasepool时是在第八行释放的,但不用释放池的话就不知道什么时候了。好乱,果然还是没学会~
作者: TLTY    时间: 2014-6-28 12:57
chain 发表于 2014-6-28 00:42
你说的是有道理,但是数组释放的时候会对数组的所有元素做一次release操作啊,最后3次release是对应前面3 ...

是啊,但是楼主说如果没有用@autoreleasepool最后运行整个程序时没有调用dealloc方法,是因为对象的计数没有为0,如果不用到@autoreleasepool想手动管理内存就要在@property声明属性时加上强指针或弱指针
作者: 刘昭    时间: 2014-6-28 13:25
本帖最后由 刘昭 于 2014-6-28 13:27 编辑

MRC里,dealloc貌似就是在autoReleasepool结束的时候,判断到retainCount == 0 然后调用的吧~~~
不用autoReleasepool的话,那楼主用ARC就行了嘛
如果用MRC的话,系统会自动对代码加上autoReleasepool来释放对象吧

作者: chain    时间: 2014-6-28 14:43
TLTY 发表于 2014-6-28 12:57
是啊,但是楼主说如果没有用@autoreleasepool最后运行整个程序时没有调用dealloc方法,是因为对象的计数 ...

如果我在函数里面用静态方法创建数组,并且把这几个对象放进去,然后在主函数的自动释放池中调用函数,你觉得对象会不会调用dealloc方法?
作者: TLTY    时间: 2014-6-28 14:57
数组的内存管理;
如果把一个对象放到一个数组里面,改对象的计数器加一。也就是说数组会对他做一次retain操作
数组被销毁([array ralease])的时,会对内部所有的元素都做一次release操作,
作者: TLTY    时间: 2014-6-28 15:00
chain 发表于 2014-6-28 14:43
如果我在函数里面用静态方法创建数组,并且把这几个对象放进去,然后在主函数的自动释放池中调用函数,你 ...

也会调用dealloc方法,因为调用函数时就相当于把函数里的代码复制到主函数的自动释放池中,因此自动池释放时,也就对数组中的对象做了一次release了




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