Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 快速内存管理:在var中存储func_Swift_Memory Management_Retain Cycle - Fatal编程技术网

Swift 快速内存管理:在var中存储func

Swift 快速内存管理:在var中存储func,swift,memory-management,retain-cycle,Swift,Memory Management,Retain Cycle,我正在寻找将函数作为变量存储在其他对象中的最佳实践。具体来说,我希望避免在函数中捕获self时保留固有的周期 来自objective-c和blocks,我通常会这样做: __weak id _self = self; iVar.someBlock = ^{ [_self doSomething]; }; 当然,iVar类将复制并存储该块。不存在保留周期,因为我捕获了\u弱id\u self 在Swift中,我不太确定,特别是因为我可以传递类函数/方法。那么,让我们假设在iVar类中,我

我正在寻找将函数作为变量存储在其他对象中的最佳实践。具体来说,我希望避免在函数中捕获
self
时保留固有的周期

来自objective-c和blocks,我通常会这样做:

__weak id _self = self;
iVar.someBlock = ^{
    [_self doSomething];
};
当然,
iVar
类将复制并存储该块。不存在保留周期,因为我捕获了
\u弱id\u 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?()
    }
}
我们这里有一个保留周期吗?我想是的,我想也许我需要让
回调变得很弱:

    weak var callBack:() -> ()?
当然,我可以在主课上做这样的事情:

    init(iVar:iVarClass){
        self.iVar = iVar
        weak var _self = self
        iVar.callback = {
            _self?.doSomething()
        }
    }
但是能够将类函数作为参数传递真是太好了!此外,如果我确实需要使
回调
弱,那么我认为我将失去为其分配闭包的能力(因为在分配之后,闭包将仅通过一个弱引用从内存中释放)

另外,请注意,内存管理责任现在是由接收方而不是由赋值方承担的,但是由于接收方无法知道赋值的来源,因此它不能真正承担责任。换言之,现在必须在接收人和转让人之间就要传递什么样的功能订立一项默示合同,这是脆弱的,不推荐的。当转让人负责时,可以采取措施确保没有保留周期,但接收方不能采取此类措施

这使我认为我们永远不应该将一个类函数传递给另一个对象。太危险了。你不知道接收器将如何存储/使用它

还是我遗漏了什么?斯威夫特在幕后神奇地解决了这个问题吗

更新 @Kirsteins指出了一些我已经忘记的东西:俘虏名单。因此,您可以在闭包中声明它,而不是显式声明
弱var\u self=self

    init(iVar:iVarClass){
        self.iVar = iVar
        iVar.callback = { [weak self] in
            self?.doSomething()
        }
    }
这更好,但远不如简单地分配类函数那么优雅

我想我想要的是Swift自动将一个类函数转换成一个带有捕获列表的闭包,这样我就不必这么做了。公平地说,这并不困难,但是如果我可以分配类函数,肯定会漂亮得多。见鬼,即使这样也会更好:

self.iVar.callback = weak self.doSomething

你不能这样做吗:

class mainClass {
    var iVar: iVarClass
    init(iVar:iVarClass){
        self.iVar = iVar
        func go() {
            self.doSomething()
        }
        iVar.callback = go
    }
    func doSomething(){
      self.iVar.jumpUpAndDown?()
    }
}

我的理解是,这样您就不会直接捕获自己,从而避免了一个保留周期。

您能找到关于这个主题的更多信息吗?我觉得奇怪的是,这个看似非常常见的用例没有相应的语法。不,我什么都没看到。似乎捕获列表就是苹果的答案。但似乎错过了一个机会,因为一个更简单的系统会使对象更具可组合性。