Fugas de memory en el parque infantil rápido / deinit {} no se llama constantemente

La eliminación de objects ARC parece ser inconsistente en Swift Playground. ¿Es un error o por layout?

Considere esta class:

class Test { var name: String init(name:String){ self.name = name println("\(name) initialized") } deinit{ println("\(name) deinitialized") } } 

Cuando lo llamo desde el patio (no la línea de command REPL, ver comentario a continuación):

 var t1 = Test(name: "t1") var t2 : Test? = Test(name: "t2") t2 = nil 

Veo solo posts de initialization en la console:

 t1 initialized t2 initialized 

Lo que falta es deinit de t2.

Cuando lo ejecuto en una aplicación (por ejemplo, la input del delegado de la aplicación), la salida es consistente con la eliminación de ARC (es decir, t1 init, entonces t2 y t2 deinit y luego t1, ya que todo el bloque de invocación queda fuera del scope):

 t1 initialized t2 initialized t2 deinitialized t1 deinitialized 

Finalmente, en la línea de command REPL (ver comentario a continuación para acceder al REPL), los resultados son consistentes, es decir: t1 está vivo debido a su scope de nivel superior, pero t2 es ARC eliminado, como era de esperar.

  1> class Test { 2. var name: String 3. init(name:String){ 4. self.name = name 5. println("\(name) initialized") 6. } 7. deinit{ 8. println("\(name) deinitialized") 9. } 10. } 11> var t1 = Test(name: "t1") t1 initialized t1 initialized t1 deinitialized t1: Test = { name = "t1" } 12> var t2 : Test? = Test(name: "t2") t2 initialized t2 initialized t2 deinitialized t2: Test? = (name = "t2") 13> t2 = nil t2 deinitialized 14> t1 $R2: Test = { name = "t1" } 15> t2 $R3: Test? = nil 

Comparamos ARC / eliminación de objeción en un escenario de aplicación y dentro del Patio de juegos. Nuestro código de testing usó un object creado dentro y fuera de un ámbito particular. También anidamos el object de testing para probar el scope de múltiples anidaciones.

Vimos que el escenario de la aplicación borra los objects directamente en la reference (reference zeroth), mientras que el escenario de Playground elimina algunos, pero se aferra a la mayoría de los objects (independientemente del scope, pero al parecer coherente en varias ejecuciones).

Probablemente, el Patio de recreo se aferra a los objects para dar service a su salida auxiliar GUI (y / o su function de reproducción).

Vea la publicación del blog aquí .

Descubrí que podía activar la llamada a deinit {} en un patio (Xcode versión 6.0 (6A313)) agregando una capa externa de opcional:

 struct MetaTest { var t3: Test? = Test(name: "t3") } var mt3: MetaTest? = MetaTest() mt3!.t3 = nil 

que crea esta salida:

 t3 initialized t3 deinitialized