从闭包的实例属性访问self

wuj*_*jek 44 swift

我正在使用Xcode6-beta2,但自第一次公开测试版以来,我遇到了同样的问题.Obj-C UIViewController的My Swift子类如下所示:

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

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

(Function)
<_TtC12SwiftiOSTest6SomeVC: 0x10bf1ed10>
<_TtC12SwiftiOSTest6SomeVC: 0x10bf1ed10>
Run Code Online (Sandbox Code Playgroud)

(c2和c3的不同之处仅在于,如果计算属性只能获取,则不必包含get {...}.)

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

这是在某处记录的(我阅读了Swift书并没有找到任何内容),或者它只是某种类型的beta编译器错误,应该在某处提交?

Ani*_*ese 60

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

惰性属性意味着您可以在默认闭包内引用self,因为在初始化完成并且已知self存在之前,将不会访问lazy属性.

你错过了@lazy所以self封闭是未知的,这就是为什么它打印它作为(Function)我的猜测.

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()
        }
}
Run Code Online (Sandbox Code Playgroud)

产量

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


更新

将闭包分配给类实例变量会导致强引用周期.你应该避免这种情况.雨燕采用捕获列表

如果为类实例的属性分配闭包,并且闭包通过引用实例或其成员来捕获该实例,则将在闭包和实例之间创建一个强引用循环.Swift使用捕获列表来打破这些强大的参考周期.有关更多信息,请参阅闭包的强引用周期.

所以关闭的正确用法可能是

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

}
Run Code Online (Sandbox Code Playgroud)

参考:Swift编程指南

编辑
@lazy已更改为懒惰