Swift中闭包的Partial apply是什么?

17

我正在尝试理解这份崩溃报告,但无法弄清楚,因为在崩溃报告中显示函数“applySettings()”并没有从init()中调用。在Swift中,“partial apply for closure#1”是什么意思?

enter image description here

以下是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是什么意思? - matt
什么是“部分应用闭包#1”? - Deepak Sharma
@Larme 在问题中添加了代码。 - Deepak Sharma
self.configuresession,那里有closure。未拥有的self和弱self之间的区别是什么? - Larme
你是否找到了 "applySettings" 与 init 中的 "partial apply for closure" 相关的原因,尽管 init 函数与 "applySettings" 函数没有直接联系呢? - Cheok Yan Cheng
显示剩余5条评论
4个回答

10

@DanielKaplan

我想要一个关于“partial apply for closure#1”含义的答案,而不是堆栈跟踪的原因。答案必须解释这个意思。

一些背景知识(来自这里 ,有关数学更深入的内容请参见 Currying):

enter image description here

那么这是怎么回事?

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

在这里,我们直接调用了闭包函数,Swift编译器会识别这一点并进行柯里化,即将函数的调用转换为闭包的解包和内部函数的直接调用,例如:

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

但是,将这个与源代码调试信息连接起来应该保留有关此简化的信息,因此他们将其标记为闭包的部分应用程序#N(其中N只是父函数中已存在的闭包的顺序号)。

为了修复之前提到的崩溃,最好的方法是完全从 init 中删除那一部分,并在创建完成后调用。更糟糕的方法是使用 [weak self],但取决于其他代码是否适用。


2
抱歉,我不太明白,尤其是在两个代码示例之间的那一段。 - Daniel Kaplan
但是,这仍然无法解释为什么“applySettings”与init中的“partial apply for closure”相关联,即使init与“applySettings”函数没有直接链接? - Cheok Yan Cheng

5

init 中不能进行异步操作。我们正试图返回已初始化的对象; 这就是你应该在这里做的所有事情。其他所有操作应在某个后续配置调用中完成,当 self 完全存在时。


3
好的观察。但在崩溃报告中,这是主要原因吗? - Deepak Sharma
2
我坚持我的答案。 - matt
这并没有回答原始问题:Swift中闭包#1的部分应用是什么? - Daniel Kaplan
@DanielKaplan 所以新的问题是,通常情况下,在堆栈跟踪中,“partial apply for closure”是什么意思?(没有人能解释 OP 的崩溃,因为 OP 没有提供足够的信息。所以我正在尝试找出您想回答的问题。) - matt
@matt 确实如此。我已经通过谷歌搜索了一段时间,并且也会感激(但不是必须的)一个标准地方让我自己学习,因为我还有很多其他问题要解决。例如,“thunk的部分应用”,“...的thunk”,“闭包#3在...”我找到了解释堆栈跟踪的每一列的文档,但我找不到关于这些术语的文档。 - Daniel Kaplan
显示剩余3条评论

3

首先声明,我并不完全自信我的回答。 但是经过查找,当一个闭包立即执行时,在Swift的堆栈跟踪中,它会显示为类似于以下内容:

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)

我希望有人可以自信地发表意见,确认这是正确的,但这只是我的猜测。

1

我收到了一个来自对 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没有显示行号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接