我想知道在使用这样的代码时是否可以删除强制解包(Swift):
var currentProductRequest : SKProductsRequest?
public func requestProducts() -> Bool {
currentProductRequest = SKProductsRequest(productIdentifiers: Set<String>(identifiers))
currentProductRequest!.delegate = self
currentProductRequest!.start()
}
在这种情况下,currentProductRequest将100%不为零;然而它是一个可选的,在上面的上下文中,编译器不知道它不会是nil而且它需要强制解包。 由于初始化SKProductsRequest永远不会产生零,所以我无法使用
if let request = SKProductsRequest(productIdentifiers: Set<String>(identifiers)) {
....
}
我知道的一种方法是将currentProductRequest的声明隐式解开,如var currentProductRequest:SKProductsRequest!。然而,这将使编译器认为currentProductRequest永远不会是nil,这可能不是这种情况。
我知道强制解包不会导致问题(在这种情况下),但它对我来说似乎很难看。有没有人知道是否有一种方法让编译器知道currentProductRequest不会为零,从而删除强制解包。
答案 0 :(得分:2)
我通常这样做的方法是创建一个非可选对象,配置它,然后将其设置为参数:
var currentProductRequest : SKProductsRequest?
public func requestProducts() -> Bool {
let productRequest = SKProductsRequest(productIdentifiers: Set<String>(identifiers))
productRequest.delegate = self
productRequest.start()
currentProductRequest = productRequest
}
已编辑添加
还有另一种方法可以做到这一点,这是一个更有人工作的方法:创建一个透明地展开可选项并返回它的公共变量,这样你就不必处理可选项:
private var _currentProductRequest : SKProductsRequest?
public var currentProductRequest: SKProductsRequest = {
return _currentProductRequest!
}()
public func requestProducts() -> Bool {
let productRequest = SKProductsRequest(productIdentifiers: Set<String>(identifiers))
productRequest.delegate = self
productRequest.start()
_currentProductRequest = productRequest
}
但这可能是过度杀人。
答案 1 :(得分:2)
在这种情况下,我更喜欢定义具有相同名称的局部常量,并使用self
关键字将其分配给属性,就像我们在初始化器中所做的那样:
var currentProductRequest : SKProductsRequest?
public func requestProducts() -> Bool {
let currentProductRequest = SKProductsRequest(productIdentifiers: Set<String>(identifiers))
self.currentProductRequest = currentProductRequest
currentProductRequest.delegate = self
currentProductRequest.start()
return true
}
答案 2 :(得分:2)
如果identifiers
不是可选的,您可以从lazy var
lazy var currentProductRequest: SKProductsRequest = {
let productRequest = SKProductsRequest(productIdentifiers: Set<String>(identifiers))
productRequest.delegate = self
return productRequest
}()
public func requestProducts() -> Bool {
currentProductRequest!.start()
}