Skip to content

Instantly share code, notes, and snippets.

@externvoid
Last active May 23, 2016 07:20
Show Gist options
  • Select an option

  • Save externvoid/42a2919cf72ea0bede6adecf9e213759 to your computer and use it in GitHub Desktop.

Select an option

Save externvoid/42a2919cf72ea0bede6adecf9e213759 to your computer and use it in GitHub Desktop.
swiftのキャプチャ機能[ ]とキャプチャ変数をunowned修飾する事で、循環参照を回避する。closure gからはselfを参照、MyClassのインスタンス(self)はmethod()を経由してclosure gを参照する。
class MyClass {
var x: Int = 10
func method() {
print("x = \(x)")
}
var g:()->() = {
let y = self.x
print(__LINE__,"行", String(self.dynamicType), __FUNCTION__)
print("y = \(y)")
}
deinit{
print("deinit")
}
}
//error: use of unresolved identifier 'self'
// let y = self.x
// ^~~~
// lazyを加えるとコンパイル可能に!
class MyClass {
var x: Int = 10
func method() {
print("x = \(x)")
}
lazy var g:()->() = {
let y = self.x
print("y = \(y)")
}
deinit{
print("deinit")
}
}
var a:MyClass? = MyClass()
a!.method()
a = nil
//x = 10
//deinit
//更にクロージャーgをmethodからcallしてみる
[quickrun output]::1/3
class MyClass {
var x: Int = 10
func method() {
print("x = \(x)")
g()
}
lazy var g:()->() = {
let y = self.x
print("y = \(y)")
}
deinit{
print("deinit")
}
}
var a:MyClass? = MyClass()
a!.method()
a = nil
//x = 10
//y = 10
//deinitが呼ばれなくなり、メモリリーク発生
//しかしselfをキャプチャし、更にunownedすれば再びdeinitされる
class MyClass {
var x: Int = 10
func method() {
print("x = \(x)")
g()
}
lazy var g:()->() = { [unowned self] in
let y = self.x
print("y = \(y)")
}
deinit{
print("deinit")
}
}
var a:MyClass? = MyClass()
a!.method()
a = nil
//x = 10
//y = 10
//deinit
//:()->()が無ければ、こんなエラーが出る。closureと型推論しない見たいだ。
//error: use of unresolved identifier 'self'
// lazy var g = { [unowned self] in
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment