Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.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
Ios 闭包递归与保持循环_Ios_Swift - Fatal编程技术网

Ios 闭包递归与保持循环

Ios 闭包递归与保持循环,ios,swift,Ios,Swift,我的结局仍然存在。它会导致捕获内部的所有其他对象。我可以使用弱引用传递这些对象,但它不能解决保留周期的问题。使用闭包进行递归而不使用retain循环的正确方法是什么 class Foo { var s = "Bar" deinit { print("deinit") // Won't be executed! } } class TestVC: UIViewController { override func viewDidLoad() { super.vie

我的结局仍然存在。它会导致捕获内部的所有其他对象。我可以使用弱引用传递这些对象,但它不能解决保留周期的问题。使用闭包进行递归而不使用retain循环的正确方法是什么

class Foo {
  var s = "Bar"
  deinit {
    print("deinit") // Won't be executed!
  }
}

class TestVC: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()

    let foo = Foo() // Weak works, but not the right solution.
    var closure: () -> Void = { return }
    closure = {
      print(foo.s)
      if true {
        return
      } else {
        closure()
      }
    }
  }

}

您的
closure
正在保存
foo
实例引用。
foo
将在
closure
发布后立即发布

closure
正在调用自身。如果我们通过弱
self
内部
closure
,那就可以了。或通过重置
关闭

override func viewDidLoad() {
    super.viewDidLoad()

    var closure: () -> Void = { return }
    closure = { [weak self] in
        let foo = Foo()
        print(foo.s)
        if true {
            return
        } else {
            self?.closure()
        }
    }
}
下面的代码应该可以正常工作

var closure: () -> Void = { return }

override func viewDidLoad() {
    super.viewDidLoad()

    let foo = Foo()

    closure = { [weak self] in
        print(foo.s)
        if true {
            return
        } else {
            self?.closure()
        }
    }
}
或初始化
foo
内部
closure

override func viewDidLoad() {
    super.viewDidLoad()

    var closure: () -> Void = { return }
    closure = { [weak self] in
        let foo = Foo()
        print(foo.s)
        if true {
            return
        } else {
            self?.closure()
        }
    }
}

您的
closure
正在保存
foo
实例引用。
foo
将在
closure
发布后立即发布

closure
正在调用自身。如果我们通过弱
self
内部
closure
,那就可以了。或通过重置
关闭

override func viewDidLoad() {
    super.viewDidLoad()

    var closure: () -> Void = { return }
    closure = { [weak self] in
        let foo = Foo()
        print(foo.s)
        if true {
            return
        } else {
            self?.closure()
        }
    }
}
下面的代码应该可以正常工作

var closure: () -> Void = { return }

override func viewDidLoad() {
    super.viewDidLoad()

    let foo = Foo()

    closure = { [weak self] in
        print(foo.s)
        if true {
            return
        } else {
            self?.closure()
        }
    }
}
或初始化
foo
内部
closure

override func viewDidLoad() {
    super.viewDidLoad()

    var closure: () -> Void = { return }
    closure = { [weak self] in
        let foo = Foo()
        print(foo.s)
        if true {
            return
        } else {
            self?.closure()
        }
    }
}

您有一个不寻常的设置,闭包会自动保留。请注意,Swift不允许创建对闭包的弱引用

要打破retain循环,请在递归的基本情况下将
closure
设置为
{}
。下面是一个测试macOS命令行程序:

func test() {
    var closure: ((Int) -> ()) = { _ in }
    closure = { i in
        if i < 10 {
            closure(i + 1)
        } else {
            // Comment out this line for unbounded memory consumption.
            closure = { _ in }
        }
    }
    closure(0)
}

while true {
    test()
}
func测试(){
变量闭包:((Int)->())={in}
闭包={i in
如果我<10{
关闭(i+1)
}否则{
//注释掉这一行的无限内存消耗。
闭包={uin}
}
}
关闭(0)
}
虽然是真的{
测试()
}
如果你运行这个,它的内存消耗是持平的


如果在重置
闭包的基本情况下注释掉该行,它的内存消耗将不受限制地增长。

在闭包保留自身的情况下,您有一个不寻常的设置。请注意,Swift不允许创建对闭包的弱引用

要打破retain循环,请在递归的基本情况下将
closure
设置为
{}
。下面是一个测试macOS命令行程序:

func test() {
    var closure: ((Int) -> ()) = { _ in }
    closure = { i in
        if i < 10 {
            closure(i + 1)
        } else {
            // Comment out this line for unbounded memory consumption.
            closure = { _ in }
        }
    }
    closure(0)
}

while true {
    test()
}
func测试(){
变量闭包:((Int)->())={in}
闭包={i in
如果我<10{
关闭(i+1)
}否则{
//注释掉这一行的无限内存消耗。
闭包={uin}
}
}
关闭(0)
}
虽然是真的{
测试()
}
如果你运行这个,它的内存消耗是持平的

如果注释掉重置
闭包的基本大小写中的行,则其内存消耗会无限增长。

将闭包转换为:

在Swift中,嵌套函数可以同步地(递归函数)或异步地(通常用于异步迭代)引用自己,可以在没有任何引用循环的情况下这样做,并且可以像闭包一样捕获变量。您甚至可以拥有相互递归的嵌套函数

您可以在完成后将包含变量的闭包重置为伪闭包,我不是说这不起作用,但这很容易出错,特别是当闭包异步调用自身时:在这种情况下,重置也必须异步完成。最好是静态地确保没有参考循环,因为在Swift中,大多数其他地方都可以这样做

(由于gcc在C语言中的一个实现,这个概念过去有一个不好的rap,该实现在试图将闭包引用压缩到C函数指针(即代码地址)时引入了安全漏洞,但Swift嵌套函数与此无关)

将闭包转换为:

在Swift中,嵌套函数可以同步地(递归函数)或异步地(通常用于异步迭代)引用自己,可以在没有任何引用循环的情况下这样做,并且可以像闭包一样捕获变量。您甚至可以拥有相互递归的嵌套函数

您可以在完成后将包含变量的闭包重置为伪闭包,我不是说这不起作用,但这很容易出错,特别是当闭包异步调用自身时:在这种情况下,重置也必须异步完成。最好是静态地确保没有参考循环,因为在Swift中,大多数其他地方都可以这样做


(由于gcc在C语言中的一个实现,这个概念过去有一个不好的rap,该实现在试图将闭包引用压缩到C函数指针(即代码地址)中时引入了安全漏洞,但Swift嵌套函数与此无关)

不,不会。我已经修改了上面的代码,让它更清晰。不,不会。我已经更改了上面的代码以使其更清晰。@matt我已经更改了代码。只有当foo很弱时才会调用Deinit。但它不能解决闭包保留周期的问题。@matt我已经更改了代码。只有当foo很弱时才会调用Deinit。但它并不能解决闭包保留周期的问题,而且闭包是一种引用类型,所以弱引用似乎是可能的和可取的。请参见示例
closure={in}
在我的案例中的帮助!谢谢然而闭包是一种引用类型,所以弱引用似乎是可能的和可取的。请参见示例
closure={in}
在我的案例中的帮助!谢谢