微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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已改为延迟

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐