何时在Objective-C程序中释放对象

时间:2014-12-26 00:26:05

标签: objective-c memory-management autorelease

我正在使用Big Nerd Ranch指南开始使用Objective C.我在第20章中讨论了该项目的问题。在高级别,该项目执行以下操作

  1. 创建3个类Person,Employee(继承自person)和Assets(Employee有一个指向Assets对象的实例变量)

  2. 然后创建2个NSMUtableARrays

    • 阵列1:员工:员工对象数组(一些指向0个资产对象,一些指向1,一些指向2个资产对象)
    • 数组2:allAssets:Array os资产对象(每个创建的Asset对象的一个​​条目)
  3. 在此之后,将释放employees数组中的一个对象。这导致此Employee对象被释放,但链接到Employee对象的资产对象不是因为allAssets数组拥有它

  4. 在此之后,我在主要回归0之前放了一个睡眠(60)

  5. 我看到如果sleep(60)在@autoreleasepool {}之后,那么所有对象在睡眠发生1分钟之前就会被解除分配

    但如果睡眠(60)发生在关闭左支撑之前,那么所有对象在睡眠发生1分钟后都会被解除分配

    为什么会这样?我认为自动释放只会在返回后启动?为什么在我将睡眠放在@autorelease {}之外的情况下返回之前,是否只是一个编译器优化,它识别此时不再需要对象,因为剩下的唯一行是sleep()?

    我已将项目上传到

    https://github.com/smartiothome/BMI

3 个答案:

答案 0 :(得分:2)

查看sleep()documentation:“sleep命令暂停执行至少几秒钟。”

基本上睡眠期间没有发生任何事情,这就是为什么它永远不应该在发布程序中使用。

在程序退出处执行此操作也将是未定义的。系统将回收应用程序发布或不发布的所有内存,以便应用程序可能决定不再在终止时释放任何内容。除此之外:操作系统内核所做的几件事之一就是处理资源,将它们作为请求提供给应用程序,并确保在正常的应用程序终止或崩溃时回收所有资源。

建议您根据应用程序关闭重新格式化 not 问题,并根据该问题打开一个新问题。

答案 1 :(得分:0)

当控件到达@autorelease池的右括号时,即当前池被告知drain时,这会导致您的对象被释放。您的睡眠呼叫会延迟drain

为了更好地了解最新情况,我建议您在添加新的NSAutoreleasePool语法之前先了解@的工作原理。这基本上是发生在幕后的事情。

答案 2 :(得分:0)

  

为什么会这样?我以为自动释放只会在之后启动   回来了吗?

当你autorelease一个对象时,当前release块(运行时调用堆栈中最内层的@autoreleasepool块)结束时,它将是@autoreleasepool d。

如果您在同一功能中@autoreleasepool周围没有autorelease阻止,那么"当前@autoreleasepool阻止&#34}是调用函数的一个调用函数,因此从当前函数返回后发生release

但是,在这种情况下,您在同一个函数中的@autoreleasepool周围有autorelease个阻止,因此release块发生在@autoreleasepool块的末尾