swift – 从作为闭包的实例属性访问自身

我使用Xcode6-beta2,但我已经有同样的问题,因为第一次公开测试版。我的Swift子类Obj-C UIViewController看起来像这样:
class SomeVC: UIViewController {
    var c1: () -> () = {
        println(self)
    }

    var c2: () -> () {
        get {
            return { println(self) }
        }
    }

    var c3: () -> () {
        return { println(self) }
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        c1()
        c2()
        c3()
    }
}

显示VC时,我看到以下行打印出来:

(Function)
<_TtC12SwiftiOSTest6SomeVC: 0x10bf1ed10>
<_TtC12SwiftiOSTest6SomeVC: 0x10bf1ed10>

(c2和c3的不同之处仅在于,如果它只有gettable,则不必包括计算属性的get {…}。)

所以,第一个闭包的自我似乎指向函数/闭包类型本身,而其他的自我指的是视图控制器(如我所料)。
c1和c2 / c3之间的唯一区别是前者是一个存储属性,后者是计算属性,但我仍然期望闭包和它们捕获的值是相同的,即self总是引用封闭类。现在的方式,似乎没有明显的方法为c1闭包访问方法/属性的封闭类。

这是记录在某处的东西(我读了Swift的书,没有找到任何东西),还是它只是一种beta编译器错误,应该提交某处?

这看起来很有趣。所以我做了一个调查。您可以从闭包中访问类实例变量,如self.instanceVariable。在那个时候,关闭将捕获它内部的自我。所以现在self指向类实例本身。你的闭包应该是一个懒惰的财产。

A lazy property means that you can refer to self within the default closure,because the lazy property will not be accessed until after initialization has been completed and self is kNown to exist.

你缺少@lazy所以自我是未知的闭包,这就是为什么它打印为(函数)我的猜测。

class TableViewController: UIViewController {
var name = "anil"
// Since swift 2.0 came out @lazy is replaced by lazy
lazy  var c1: () -> () = {
    println(self)
    println(self.name)

}

var c2: () -> () {
get {
    return { println(self) }
}
}

var c3: () -> () {
return { println(self) }
}


  override func viewDidLoad() {
        super.viewDidLoad()
        c1()
        c2()
        c3()
        }
}

输出

<_TtC12TableViewApp19TableViewController: 0x10d54e000>
anil
<_TtC12TableViewApp19TableViewController: 0x10d54e000>
<_TtC12TableViewApp19TableViewController: 0x10d54e000>

更新

将闭包分配给类实例变量会产生很强的参考周期。你应该避免这个。 Swift使用Capture列表

If you assign a closure to a property of a class instance,and the closure captures that instance by referring to the instance or its members,you will create a strong reference cycle between the closure and the instance. Swift uses capture lists to break these strong reference cycles. For more information,see 07000.

所以正确使用闭包可以

@lazy  var c1: () -> () = {
    [uNowned self] in
    println(self)
    println(self.name)

}

参考:Swift programming guide

编辑@lazy已改为延迟

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...