Swift 操场中的弱引用无法按预期工作 [英] Weak references in Swift playground don't work as expected

查看:28
本文介绍了Swift 操场中的弱引用无法按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在 Playground 中关注 Intermediate Swift WWDC session 中的弱引用示例.我稍微修改了代码如下:

I have been following the weak referencing example from the Intermediate Swift WWDC session in a Playground. I modified the code slightly as follows:

class Apartment {
    let address: Int

    init(address: Int) {
        self.address = address
    }

    weak var tenant: Person?
}

class Person {
    let name: String

    init(name: String){
        self.name = name
    }

    weak var home: Apartment?

    func moveIn(apt: Apartment) {
        self.home = apt
        apt.tenant = self
    }
}

var renters = ["John Appleseed": Person(name: "John Appleseed")]
var apts = [16: Apartment(address: 16)]

renters["John Appleseed"]!.moveIn(apts[16]!)
renters["John Appleseed"] = nil // memory should be released here

// then apts[16].tenant should be nil
if let tenantName = apts[16]!.tenant?.name {
    // this should only execute if the Person object is still in memory
    println("\(tenantName) lives at apartment number \(apts[16]!.address)")
} else {
    // and this line should execute if the memory is released as we expect
    println("Nobody lives at apartment number \(apts[16]!.address)")
}

// Console output in Playground: John Appleseed lives at apartment number 16
// Console output in standalone app: Nobody lives at apartment number 16

根据我对弱引用的理解,为 Person 实例分配的内存应该在从租用者字典中删除时释放,因为对它的唯一其他引用是弱引用.但是,如果程序作为独立命令行应用程序运行与在 Playground 中运行,则该程序的输出是不同的(请参阅评论).

From my understanding of weak referencing, the memory allocated for the instance of Person should be released when it is removed from the renters dictionary because the only other reference to it is weak. However, the output of the programme is different if it is run as a standalone command line application vs. in a Playground (see comments).

推荐答案

我相信顶级函数 (REPL/playground) 会保持强引用以促进交互行为,并在帧返回时进行清理.此行为消除了交互环境中的内存泄漏.

I believe the top-level function (REPL/playground) is keeping a strong reference to facilitate interactive behavior, and cleaning up when the frame returns. This behavior eliminates memory leaks in the interactive environment.

我复制了 Viktor 的简单示例并使用了 xcrun swift REPL.

I copied Viktor's simple example and used the xcrun swift REPL.

在 REPL 模式下,我将逻辑包装在一个函数中,它按预期工作.如果/当您关心何时清理内存,我建议将您的逻辑包装在一个函数中.

In REPL mode, I wrapped the logic in a function and it works as expected. If/when you care when the memory is cleaned up, I would suggest wrapping your logic in a function.

// declaration of the types
class Person {
   let name: String
   weak var home: Apartment?

  init(pName: String){
      name = pName
  }

}

class Apartment {
    let postalCode: Int

    init(pPostalCode: Int) {
        postalCode = pPostalCode
    }
}

func testArc() {
    // create Person object
    var personJulius: Person = Person(pName: "Julius")

    // create Apartment object
    var apartmentBerlin: Apartment? = Apartment(pPostalCode: 10777)

    // connect Apartment object and Person object
    personJulius.home = apartmentBerlin

    // Set only strong reference of Apartment object to nil
    apartmentBerlin = nil

    // Person object should now have nil as home
    if personJulius.home != nil {
        println("Julius does live in a destroyed apartment")
    } else {
        println("everything as it should")
    }

}

//outputs "everything as it should"
testArc()

这篇关于Swift 操场中的弱引用无法按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆