【发布时间】:2021-01-25 20:58:36
【问题描述】:
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
hideActivity()
let products = response.products
if products.count > 0{
let controller = HAPurchaseViewController.instantiate() // crashes here
controller.categories = dataManager.paidCategories()
controller.products = products
self.navigationController?.pushViewController(controller, animated: true)
}
else{
DispatchQueue.main.async { [weak self] in
let alertController = UIAlertController(title: "Oops!", message: "Unable to load or products not found, please try again later", preferredStyle: .alert)
let okAction = UIAlertAction(title: "Ok", style: .default)
alertController.addAction(okAction)
self?.present(alertController, animated: true)
}
}
}
除了我使用它来加载我的应用内购买视图控制器时,这个扩展在其他任何地方都可以使用。
import Foundation
import UIKit
protocol Storyboarded {
static func instantiate() -> Self
}
extension Storyboarded where Self: UIViewController {
static func instantiate() -> Self {
let id = String(describing: self)
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
if #available(iOS 13.0, *) {
return storyboard.instantiateViewController(identifier: id) as! Self // App crash here when loading storyboard
} else {
return storyboard.instantiateViewController(withIdentifier: id) as! Self
}
}
static func value() -> Self {
return UIViewController() as! Self
}
}
=================================================================
Main Thread Checker: UI API called on a background thread: -[UIViewController initWithCoder:] > PID: 13525, TID: 4347723, Thread name: (none), Queue name: com.apple.root.default-qos, QoS: 0
Backtrace:
根据 SO 的建议,我更新了代码
extension Storyboarded where Self: UIViewController {
static func instantiate() -> Self {
DispatchQueue.main.async {
let id = String(describing: self)
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
if #available(iOS 13.0, *) {
return storyboard.instantiateViewController(identifier: id) as! Self
} else {
return storyboard.instantiateViewController(withIdentifier: id) as! Self
}
}
}
static func value() -> Self {
return UIViewController() as! Self
}
}
【问题讨论】:
-
UI API called on a background thread,这很明确。在哪里调用let controller = HAPurchaseViewController.instantiate()放在DispatchQueue.main.async {}中。 -
是否有带有该标识符的情节提要或该类是否以编程方式定义?如果是这样,您肯定会遇到问题。
-
问题是您错误地调用了
Storyboarded.instantiate()— 即,来自后台线程。但是您没有显示该代码,因此无法多说。同时,正如您被告知的那样,错误是完全不言自明的,不应该出现任何问题。 -
@matt 用代码更新了问题并发布了新的错误图片
标签: swift model-view-controller storyboard