我正在寻找将函数存储为其他对象变量的最佳实践。具体来说,我希望避免在函数中捕获self
时固有的保留周期。
来自objective-c和blocks,我通常会这样做:
__weak id _self = self;
iVar.someBlock = ^{
[_self doSomething];
};
当然,iVar
类会复制块并存储它。没有保留周期,因为我捕获了__weak id _self
。
在Swift中,我不太确定,特别是因为我可以传递类函数/方法。所以,我想在iVar
课程中说:
class iVarClass {
var callBack:() -> ()?
func jumpUpAndDown(){
//Weeeeeee!
self.callBack?()
}
}
现在在我的“main”类中,我有一个上面类的实例变量,我这样做:
class mainClass {
var iVar: iVarClass
init(iVar:iVarClass){
self.iVar = iVar
iVar.callback = self.doSomething
}
func doSomething(){
self.iVar.jumpUpAndDown?()
}
}
我们这里有保留周期吗?我会这么认为,我想也许我需要让callback
弱:
weak var callBack:() -> ()?
当然,我可以在主要课程中做这样的事情:
init(iVar:iVarClass){
self.iVar = iVar
weak var _self = self
iVar.callback = {
_self?.doSomething()
}
}
但能够将类函数作为参数传递真是太好了!另外,如果我确实需要使callback
弱,那么我认为我将失去为它分配一个闭包的能力(因为在赋值之后,闭包将从只有一个弱引用的内存中释放)。
另外,请注意内存管理责任的责任现在是如何在接收方而不是分配方,但由于接收方无法知道分配的来源,因此无法真正承担责任。换句话说,接收者和分配者之间必须有一个隐含的契约,要求传递什么样的功能,这是脆弱的而不是推荐的。当分配者负责时,可以采取措施确保没有保留周期,但接收者不能采取这些步骤。
这让我觉得我们应该从不将类函数传递给另一个对象。这太危险了。您无法知道接收器将如何存储/使用它。
或者我错过了什么?斯威夫特在幕后神奇地解决了这个问题吗?
weak var _self = self
,而是可以在闭包中声明它:
init(iVar:iVarClass){
self.iVar = iVar
iVar.callback = { [weak self] in
self?.doSomething()
}
}
这更好,但不如简单地分配类函数那么优雅。
我认为我想要的是让Swift自动将类函数转换为带有捕获列表的闭包,所以我不必这样做。公平地说,这并不是很难,但如果我可以分配类函数,肯定会更漂亮。天哪,即使这样会更好:
self.iVar.callback = weak self.doSomething
答案 0 :(得分:0)
你做不到这样的事情:
class mainClass {
var iVar: iVarClass
init(iVar:iVarClass){
self.iVar = iVar
func go() {
self.doSomething()
}
iVar.callback = go
}
func doSomething(){
self.iVar.jumpUpAndDown?()
}
}
我的理解是,通过这种方式,您不会直接捕获self
,从而避免保留周期。