什么是 Swift 中的部分申请闭包#1

Posted

技术标签:

【中文标题】什么是 Swift 中的部分申请闭包#1【英文标题】:What is Partial apply for closure#1 in Swift 【发布时间】:2020-10-30 09:05:28 【问题描述】:

我试图理解这个崩溃报告,但没有意义,因为函数“applySettings()”不是从 init() 调用的,如崩溃报告中所示。什么是 Swift 中的“部分申请关闭#1”?

这是 init() 函数所需的代码。

   public override init()

    super.init()
    
    discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera, AVCaptureDevice.DeviceType.builtInDualCamera, AVCaptureDevice.DeviceType.builtInTelephotoCamera, AVCaptureDevice.DeviceType.builtInDualWideCamera,
            AVCaptureDevice.DeviceType.builtInTripleCamera,
            AVCaptureDevice.DeviceType.builtInUltraWideCamera], mediaType: AVMediaType.video, position: .unspecified)
    
    detectLenses()
    
    checkForDeviceAuthorization()
    
    setZoomParams()
    
    sessionQueue.async  [unowned self] in
        self.configureSession()
    


【问题讨论】:

什么是 CapturePipeline.init? CapturePipeline() 类中的 init() 函数 什么是“部分申请关闭#1”? 你介意分享CapturePipeline.init()的代码吗?在那段代码中可能有一个闭包。见那里:***.com/questions/47093409/… 方法中没有闭包作为参数,但在该代码内部有带闭包的方法。 @Larme 添加了问题中的代码。 【参考方案1】:

您不能在 init 中执行异步操作。我们正在尝试返回初始化的对象;这就是你应该在这里做的所有。当self 完全存在时,其他一切都应该在后续的配置调用中发生。

【讨论】:

这是一个很好的观察。但这是崩溃报告中的罪魁祸首吗? 另外,从 init() 调用 buildSession() 之类的函数有什么不同。而在 buildSession() 中,我们做了一个 async? 我坚持我的回答。 这是我听到的新鲜事,请原谅我的无知。通常我会在 init() 中看到函数调用的数量。在这些函数调用中,可能有许多异步。你的意思是一个错误的范式吗?有没有相同的文档? 这没有回答原来的问题:什么是部分适用于 Swift 中的闭包#1?【参考方案2】:

@丹尼尔卡普兰

我正在寻找 TITLE 的答案(就像 OP 一样),而不是原因 堆栈跟踪。答案必须说明什么是“部分申请 闭包#1”的意思。

一点背景知识(来自here,更深入的in math):

那到底是怎么回事?

sessionQueue.async  [unowned self] in
    self.configureSession()

这里我们直接有闭包调用函数,swift编译器识别出这个并进行柯里化,即。而不是调用函数的函数,解包闭包并注入async直接调用内部函数,如

sessionQueue.async(execute: CapturePipeline.configureSession(self))

但要将其与源代码调试信息结合起来,应该保留有关此简化的信息,因此他们将其标记为 部分申请闭包#(其中 N 只是父函数中已存在闭包的排序数) .

如前所述,修复该崩溃最好的是从init 中删除该部分并在创建完成后调用。更糟糕的是使用[weak self],但取决于其他代码可能适用。

【讨论】:

嗯,对不起,我没看懂,主要是两个代码示例之间的那段。【参考方案3】:

我得到了一个partial apply for closure,它是由对nil 的模运算(%)产生的。不过可能不是真正的原因。

我有这个:

if myArray.count == 0 
    return

let i = foo % (myArray.count)!

通过将其更改为修复:

if myArray.count == nil || myArray.count == 0 
    return

let i = foo % (myArray.count)!

然而,帮助我发现问题的是从 TestFlight 下载 dSYM 文件并将它们上传到 NewRelic,这向我显示了我自己的代码中发生崩溃的确切行。

这在 XCode 中也应该是可行的,但由于某种原因,XCode 这次没有向我显示行号。

【讨论】:

【参考方案4】:

我首先要说我对自己的答案并不完全有信心。 但是在 Swift stacktrace 中环顾一番之后,当一个闭包立即执行时,它会显示为类似

closure #1 in MyAppTabBarController.initialSetup() + 1028 (MyAppTabBarController.swift:469)

当它不是立即返回时(例如网络调用),它会显示为部分应用,例如

partial apply for closure #1 in closure #1 in DataRequest.response(queue:responseSerializer:completionHandler:) + 56 (ResponseSerialization.swift:167)

我希望有人插话并自信地说就是这样,但这是我的猜测。

【讨论】:

以上是关于什么是 Swift 中的部分申请闭包#1的主要内容,如果未能解决你的问题,请参考以下文章

银行的SWIFT码是啥?每个银行都有吗

在 Swift 3 中,申请为 ios 8.1 注册通知

JS高级——内存管理和闭包

JS高级——内存管理和闭包

JS高级——内存管理和闭包

Swift 闭包中的 $0 和 $1 是啥意思?