在对象初始化后防止强制可选的展开

时间:2016-08-03 11:43:38

标签: swift swift2 forced-unwrapping

我想知道在使用这样的代码时是否可以删除强制解包(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不会为零,从而删除强制解包。

3 个答案:

答案 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()
}