未设置的代表崩溃

时间:2018-08-11 14:11:59

标签: ios swift

我有一个使用委托的viewcontroller。视图正在打开,带有一个条形按钮项目。并在“后退”按钮上或“后退”按钮上“关闭”。

很遗憾,代码崩溃了,我自己不能重现代码,但是我有几个崩溃报告。它在此行崩溃:

request.delegate = nil;

而且我认为必须这样做,当视图再次打开时,委托已经为零,而我认为那不好吗?

这是我的代码(我删除了很多方法使其更加清晰):

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 个答案:

答案 0 :(得分:1)

您的request变量是一个隐式展开的可选变量,在进入清除nil属性之前,您无需检查它是否在viewWillDisappear(_:)中是delegate。 / p>

如果未将用户的设备设置为进行付款(SKPaymentQueue.canMakePayments()返回false),则您永远不会将request设置为任何值,因此nil就是这样。当您离开视图控制器时,viewWillDisappear(_:)会解开nil,这将使其崩溃。

这是一个很好的示例,说明了为什么通常最好避免隐式解包的可选内容。如果您的代码使用常规的可选字符,则可以用if let对其进行包装,并跳过viewWillDisappear(_:)中的重置逻辑。