Ios 在Swift中将函数分配给块时捕获语义?
我想知道在Swift中为一个块分配一个函数在内存管理方面意味着什么(即,我想避免一个保留周期) 例如,假设我有一个具有以下定义的按钮:Ios 在Swift中将函数分配给块时捕获语义?,ios,swift,memory-management,automatic-ref-counting,retain-cycle,Ios,Swift,Memory Management,Automatic Ref Counting,Retain Cycle,我想知道在Swift中为一个块分配一个函数在内存管理方面意味着什么(即,我想避免一个保留周期) 例如,假设我有一个具有以下定义的按钮: class Button { var wasTapped: () -> Void } 我在视图控制器中使用它,如下所示: class ViewController { let button: Button func setUpButtonHandler() { button.wasTapped = ... } func b
class Button {
var wasTapped: () -> Void
}
我在视图控制器中使用它,如下所示:
class ViewController {
let button: Button
func setUpButtonHandler() {
button.wasTapped = ...
}
func buttonWasTapped() {
// do something
}
}
我的问题是关于button.wasTapped=…
的分配
显然,如果我这样设置:
button.wasTapped = { self.buttonWasTapped() }
我刚刚创建了一个保留循环:ViewController->Button->ViewController
但是,Swift允许我这样做:
button.wasTapped = buttonWasTapped
这样做安全吗?(即,这是否会阻止保留周期?仍然会创建保留周期 思考这个问题的一个好方法是认识到,无论何时,只要你看到:
button.wasTapped = buttonWasTapped
这只是以下的简写:
button.wasTapped = { self.buttonWasTapped() }
这显然创造了一个保留周期,正如self
的明确使用所表明的那样
这令人困惑,因为保留周期在第二个版本中很明显,但在第一个版本中却不明显。
不幸的是,这意味着您需要坚持更详细的内容(并保留循环):
您可以通过以下方式验证此行为:
class Button {
var wasTapped: () -> Void
init() {
wasTapped = {}
}
}
class ViewController {
let button: Button
func setUpButtonHandler() {
//button.wasTapped = { [weak self] in self?.buttonWasTapped() } // no retain cycle
//button.wasTapped = { self.buttonWasTapped() } // retain cycle
//button.wasTapped = buttonWasTapped // retain cycle
}
func buttonWasTapped() {
print("tapped!")
}
init() {
button = Button()
setUpButtonHandler()
}
deinit {
print("deinit")
}
}
func test() {
let vc = ViewController()
vc.button.wasTapped()
}
test()
更新:更多详细信息可在此处找到:这仍然会创建保留周期 思考这个问题的一个好方法是认识到,无论何时,只要你看到:
button.wasTapped = buttonWasTapped
这只是以下的简写:
button.wasTapped = { self.buttonWasTapped() }
这显然创造了一个保留周期,正如self
的明确使用所表明的那样
这令人困惑,因为保留周期在第二个版本中很明显,但在第一个版本中却不明显。
不幸的是,这意味着您需要坚持更详细的内容(并保留循环):
您可以通过以下方式验证此行为:
class Button {
var wasTapped: () -> Void
init() {
wasTapped = {}
}
}
class ViewController {
let button: Button
func setUpButtonHandler() {
//button.wasTapped = { [weak self] in self?.buttonWasTapped() } // no retain cycle
//button.wasTapped = { self.buttonWasTapped() } // retain cycle
//button.wasTapped = buttonWasTapped // retain cycle
}
func buttonWasTapped() {
print("tapped!")
}
init() {
button = Button()
setUpButtonHandler()
}
deinit {
print("deinit")
}
}
func test() {
let vc = ViewController()
vc.button.wasTapped()
}
test()
更新:更多详细信息可在此处找到:帮助帖:)+1帮助帖:)+1