Ios 闭包递归与保持循环
我的结局仍然存在。它会导致捕获内部的所有其他对象。我可以使用弱引用传递这些对象,但它不能解决保留周期的问题。使用闭包进行递归而不使用retain循环的正确方法是什么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
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}
在我的案例中的帮助!谢谢