1

我想知道在使用这样的代码时是否可以删除强制展开(Swift):

var currentProductRequest : SKProductsRequest?

public func requestProducts() -> Bool {
    currentProductRequest = SKProductsRequest(productIdentifiers: Set<String>(identifiers))
    currentProductRequest!.delegate = self
    currentProductRequest!.start()
}

在这种情况下 currentProductRequest 将 100% 不为零;然而,它是可选的,在上述上下文中,编译器不知道它不会为 nil,它需要强制展开。由于初始化 SKProductsRequest 永远不会产生 nil 我不能使用

if let request = SKProductsRequest(productIdentifiers: Set<String>(identifiers)) {
    ....
}

我知道的一种方法是让 currentProductRequest 的声明像 var currentProductRequest : SKProductsRequest! 一样隐式展开。然而,这会使编译器认为 currentProductRequest 永远不会是 nil,但事实可能并非如此。

我知道强制展开永远不会导致问题(在这种情况下),但它对我来说似乎很难看。有谁知道是否有办法让编译器知道 currentProductRequest 不会为零,从而消除强制解包。

4

3 回答 3

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
}

但这可能是过度杀戮。

于 2016-08-03T11:46:58.750 回答
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
}
于 2016-08-03T11:57:04.440 回答
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()
}
于 2016-08-03T11:57:55.643 回答