使用可选参数的转义完成处理程序有时会使 Swift 崩溃

Posted

技术标签:

【中文标题】使用可选参数的转义完成处理程序有时会使 Swift 崩溃【英文标题】:Escaping completion handler that takes optional argument sometimes crashes Swift 【发布时间】:2019-01-31 11:33:41 【问题描述】:

我有这个代码:

 func function(completion: @escaping (_ error: Error?) -> Void)
    getSomethingFromUrl (result) in
        guard let documentData = result.property else 
            completion(nil) //crashes with error Thread 1: EXC_BREAKPOINT (code=1, subcode=0x102ba1774)
            return
        
    

有时它会在 completion(nil) 行 崩溃,并带有错误代码

线程 1:EXC_BREAKPOINT(代码=1,子代码=0x102ba1774)

考虑到参数是可选的,我不知道为什么它会崩溃,我只是将 nil 传递给它。

这是我用来调用完成处理程序的确切代码。它位于 firestore 事务的完成块中:

let docSizesRef = FirebaseHelper.References.firestoreReference.collection(FirestoreCollections.onlineUsers).document(FirestoreDocuments.documentSizeTracker)
                            FirebaseHelper.References.firestoreReference.runTransaction( (transaction, errorPointer) -> Any? in
                                let docSizesDocument: DocumentSnapshot
                                do 
                                    try docSizesDocument = transaction.getDocument(docSizesRef)
                                 catch let fetchError as NSError 
                                    errorPointer?.pointee = fetchError
                                    return nil
                                

                                let oldCount = docSizesDocument.data()?[documentIdToWriteTo] as? Int ?? 0

                                transaction.updateData([documentIdToWriteTo: oldCount + 1], forDocument: docSizesRef)
                                return nil
                            )  (object, error) in
                                completion(error)
                                if let error = error 
                                    print("Transaction failed: \(error)")
                                 else 
                                    print("Transaction successfully committed!")
                                
                            

这里是处理完成的代码

func addUserToOnlineDocs()
                User.shared.managers.accountManager.addToOnlineDocs(completion:  (error) in
                    if let error = error
                        self.createTwoButtonAlert(title: AlertErrors.Account.Titles.errorAddingToOnlineList, message: error.localizedDescription, rightButtonText: self.retryButton, leftButtonText: self.ignoreButton, rightButtonStyle: .cancel, leftButtonStyle: .default, completion:  (buttonPressed) in
                            if buttonPressed == self.retryButton
                                connectionSetup()
                            
                        )
                        return
                    
                    self.loadingCompleteDispatchGroup.leave()
                )
            

可能与事务多次调用完成处理程序有关吗?

【问题讨论】:

参数补全的代码是什么? 只做 if let error = error code.. elseleave dispatch group 我认为这与调度组离开与输入不匹配有关 您的代码中没有调度组。请显示可以重现问题的确切代码。 这很有趣。还请发布调用完成处理程序的代码。 【参考方案1】:

尝试添加; 否则 完成(无);返回

【讨论】:

以上是关于使用可选参数的转义完成处理程序有时会使 Swift 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Swift 完成处理程序 - 转义尾随闭包

Swift 4 将参数添加到 URLRequest 完成处理程序

如何在 Swift 中创建一个我可以选择调用的完成处理程序?

Swift:如何调用其中一个参数是完成处理程序的函数

Swift中带有可选完成块的函数[重复]

Swift 5:转义闭包捕获'inout'参数