代码之家  ›  专栏  ›  技术社区  ›  da1lbi3

未设置的委托正在崩溃

  •  -1
  • da1lbi3  · 技术社区  · 7 年前

    很难控制代码崩溃,我自己无法复制,但我有几个崩溃报告。它在这条线上崩溃了:

    我认为当视图再次打开时,它必须这样做,代表已经是零了,而我认为这不好吗?

    import Foundation
    import UIKit
    import FirebaseDatabase
    import StoreKit
    
    class Premium : UITableViewController, SKPaymentTransactionObserver, SKProductsRequestDelegate {
    
        override func viewDidLoad() {
    
            NotificationCenter.default.addObserver(self, selector: #selector(onHasPayed(notification:)), name: .hasPayed, object: nil)
    
    
            if SKPaymentQueue.canMakePayments() {
                print("starting IAPS")
                let productIdentifiers = Set([ audioWifi, audioVideo4G, deluxe])
    
                self.request = SKProductsRequest(productIdentifiers: productIdentifiers as Set<String>)
                self.request.delegate = self
                self.request.start()
    
    
            } else {
                print("please enable IAPS")
            }
        }
    
        @objc func onHasPayed(notification: NSNotification) {
            redirect()
        }
    
        private func redirect(){
            let appDelegate = UIApplication.shared.delegate! as! AppDelegate
    
            let initialViewController = self.storyboard!.instantiateViewController(withIdentifier: "hh")
            appDelegate.window?.rootViewController = initialViewController
            appDelegate.window?.makeKeyAndVisible()
        }
    
    
        private var request: SKProductsRequest!
    
    
        override func viewWillDisappear(_ animated: Bool) {
            request.delegate = nil;
            request.cancel()
            request = nil;
    
        }
    }
    

    在哪里需要设置请求委托,在哪里需要取消设置它?因为,我不知道出了什么问题,因为我自己无法模拟。

    可能的解决方案:

        private var request: SKProductsRequest?
    
        if SKPaymentQueue.canMakePayments() {
                    print("starting IAPS")
                    let productIdentifiers = Set([ audioWifi, audioVideo4G, deluxe])
    
                    self.request = SKProductsRequest(productIdentifiers: productIdentifiers as Set<String>)
                    self.request?.delegate = self
                    self.request?.start()
                } else {
                    print("please enable IAPS")
                }
    
    override func viewWillDisappear(_ animated: Bool) {
            if let req = request {
                req.delegate = nil;
                req.cancel()
            }
        }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Steve Madsen    7 年前

    你的 request 变量是隐式展开的可选变量,您不检查它是否 nil viewWillDisappear(_:) 在伸手清理之前 delegate 财产。

    如果用户的设备未设置为付款( SKPaymentQueue.canMakePayments() 回报 false ),你从未设定 对任何事都是如此 . 离开视图控制器时, 视图将消失(!) ,它就会崩溃。

    这是一个很好的例子,说明了为什么通常最好避免隐式展开选项。如果你的代码使用了常规的可选代码,你可以用 if let 视图将消失(!) .