我有一个使用委托的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()
}
}
答案 0 :(得分:1)
您的request
变量是一个隐式展开的可选变量,在进入清除nil
属性之前,您无需检查它是否在viewWillDisappear(_:)
中是delegate
。 / p>
如果未将用户的设备设置为进行付款(SKPaymentQueue.canMakePayments()
返回false
),则您永远不会将request
设置为任何值,因此nil
就是这样。当您离开视图控制器时,viewWillDisappear(_:)
会解开nil
,这将使其崩溃。
这是一个很好的示例,说明了为什么通常最好避免隐式解包的可选内容。如果您的代码使用常规的可选字符,则可以用if let
对其进行包装,并跳过viewWillDisappear(_:)
中的重置逻辑。