我正在使用Big Nerd Ranch指南开始使用Objective C.我在第20章中讨论了该项目的问题。在高级别,该项目执行以下操作
创建3个类Person,Employee(继承自person)和Assets(Employee有一个指向Assets对象的实例变量)
然后创建2个NSMUtableARrays
在此之后,将释放employees数组中的一个对象。这导致此Employee对象被释放,但链接到Employee对象的资产对象不是因为allAssets数组拥有它
在此之后,我在主要回归0之前放了一个睡眠(60)
我看到如果sleep(60)在@autoreleasepool {}之后,那么所有对象在睡眠发生1分钟之前就会被解除分配
但如果睡眠(60)发生在关闭左支撑之前,那么所有对象在睡眠发生1分钟后都会被解除分配
为什么会这样?我认为自动释放只会在返回后启动?为什么在我将睡眠放在@autorelease {}之外的情况下返回之前,是否只是一个编译器优化,它识别此时不再需要对象,因为剩下的唯一行是sleep()?
我已将项目上传到
答案 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
块的末尾