简体   繁体   English

swift playground / deinit {}中的内存泄漏并未始终如一地调用

[英]Memory leaks in the swift playground / deinit{} not called consistently

ARC object deletion seems to be inconsistent in the Swift Playground. 在Swift Playground中,ARC对象删除似乎不一致。 Is it a bug or by design? 这是一个bug还是设计?

Consider this class: 考虑这个课程:

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

When I call it from the playground (not the command line REPL, see comment below): 当我从操场上调用它时(不是命令行REPL,请参阅下面的注释):

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

I see only initialization messages in the console: 我在控制台中只看到初始化消息:

t1 initialized
t2 initialized

What's missing is deinit of t2. 缺少的是t2的deinit。

When I run it in an app (eg entry of app delegate), I the output is consistent with ARC deletion (ie t1 init, then t2, and t2 deinit and then t1, since the entire invocation block goes out of scope): 当我在app中运行它时(例如app delegate的条目),我输出与ARC删除一致(即t1 init,然后是t2,t2 deinit然后是t1,因为整个调用块超出了范围):

t1 initialized
t2 initialized
t2 deinitialized
t1 deinitialized

Finally, in the command line REPL (see comment below for accessing the REPL), the results are consisent, ie: t1 is alive due to its top level scope, but t2 is ARC deleted, as one would expect. 最后,在命令行REPL中(请参阅下面的注释以访问REPL),结果是明确的,即:t1由于其顶级范围而处于活动状态,但是t2被ARC删除,正如人们所期望的那样。

  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

We compared ARC/deletion of objection in an app scenario and within the Playground. 我们在应用场景和Playground中比较了ARC /删除异议。 Our test code used object created inside and outside a particular scope. 我们的测试代码使用在特定范围内外创建的对象。 We also nested the tester object to test multi-nested scoping. 我们还嵌套了测试对象以测试多嵌套作用域。

We saw that the app scenario deletes objects right on cue (zeroth reference) whereas the Playground scenario deletes a few, but holds on to a majority of objects (irrespective of scope, but apparently consistent over multiple runs). 我们看到应用程序场景在cue上删除了对象(第0个引用),而Playground场景删除了一些,但是保留了大多数对象(不考虑范围,但在多次运行时显然是一致的)。

The Playground probably holds on to objects in order to service its assistant GUI output (and/or its playback feature). Playground可能保留对象以便为其辅助GUI输出(和/或其回放功能)提供服务。

See blog post here . 在这里查看博客文章。

I found that I could trigger the call to deinit{} in a playground (Xcode version 6.0 (6A313)) by adding an outer layer of optional: 我发现我可以通过添加一个可选的外层来触发操场中的deinit {}(Xcode版本6.0(6A313))。

struct MetaTest {
   var t3: Test? = Test(name: "t3")
}

var mt3: MetaTest? = MetaTest()
mt3!.t3 = nil

which creates this output: 这会创建此输出:

t3 initialized
t3 deinitialized

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM