gpt4 book ai didi

ios - Swift 中奇怪的保留周期

转载 作者:行者123 更新时间:2023-11-28 14:38:24 25 4
gpt4 key购买 nike

所以我写了一些代码来更好地处理保留循环。

class AnotherViewController : UIViewController{

var closure : ((() -> Int) -> ())!


override func viewDidLoad() {
super.viewDidLoad()

closure = self.someFunctionWithNonescapingClosure

}

func someFunctionWithNonescapingClosure(closure: () -> Int) {
// closure()
}

显然,将 viewController 中的函数之一分配给属性闭包,会导致保留循环问题。

但是我不知道怎么办?

Self 对 Closure 有很强的引用但是,是否在 viewController tp Closure 中分配一个函数,将 self 强引用到闭包中?

谢谢

编辑 ------

显然,如果您通过创建 AnotherViewController 在 playground 中尝试此操作,将其初始化并将其分配给变量,然后将变量设置为 nil,它将成功取消初始化 AnotherViewController,但如果您在应用程序中尝试, AnotherViewController 不会被取消。

你可以尝试在AnotherViewController中添加一个按钮然后关闭它,为了方便,按钮代码是这样的

 private func addAButton(){
let button = UIButton()
let buttonBounds = CGRect(x: 0, y: 0, width: 200, height: 200)
let buttonCenter = view.center
button.bounds = buttonBounds
button.center = buttonCenter

view.addSubview(button)

button.backgroundColor = .red

button.addTarget(self, action: #selector(goBack), for: .touchUpInside)
}

@objc func goBack(){
dismiss(animated: true, completion: nil)
}

最佳答案

你的 closure正在分配一个实例 方法,该方法隐式捕获 self ,因此循环。

尝试以下应用:

import Cocoa

class Cycle
{
var closure : ((() -> Int) -> ())!

init()
{
closure = self.someFunctionWithNonescapingClosure
}

func someFunctionWithNonescapingClosure(closure: () -> Int)
{
print("Hello") // breakpoint on this line
}
}

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate
{
@IBOutlet weak var window: NSWindow!

func applicationDidFinishLaunching(_ aNotification: Notification)
{
let aCycle = Cycle()
aCycle.closure({ 42 })
}
}

print 上添加断点行并运行应用程序。

应用程序将在 someFunctionWithNonescapingClosure() 内停止由 aCycle.closure({ 42 }) 调用.

看变量显示,有一个self .这是因为每个实例方法都有一个隐式 self争论。

在您的代码中,self 在哪里?从哪里来?

当行:

closure = self.someFunctionWithNonescapingClosure

被执行 Swift 捕获当前值 self作为隐式参数传递给 someFunctionWithNonescapingClosure() ,它必须在您从实例方法创建闭包时执行此操作。

所以你有你的循环,闭包分配给 closure包含对 self 的引用.

查看此注释的值self当调试器停止时,然后选择 applicationDidFinishLaunching 的条目在堆栈跟踪中查看其 aCycle变量 - 它与 self 具有相同的值的 someFunctionWithNonescapingClosure - 有你的周期。

在堆栈跟踪中,您还会看到诸如“部分应用”之类的条目 - 这是提供的参数 ( { 42 } ) 和隐式捕获的 self 的位置收集并传递给 someFunctionWithNonescapingClosure() .

如果将代码更改为:

  init()
{
closure = Cycle.someFunctionWithNonescapingClosure
}

static func someFunctionWithNonescapingClosure(closure: () -> Int)
{
print("Hello") // breakpoint on this line
}

即制作someFunctionWithNonescapingClosure一个类 ( static ) 方法而不是一个实例,那么当前类实例不会在闭包中捕获,您将不会得到一个循环。

HTH

关于ios - Swift 中奇怪的保留周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50711659/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com