2016-08-03 3 views
0

мне было интересно, если это возможно, чтобы удалить принудительное разворачивание (Swift) при использовании такого кода:Предотвращения принудительного дополнительные развёрток после инициализации объекта

var currentProductRequest : SKProductsRequest? 

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

В этом случае currentProductRequest будет 100% не может быть нулем; он, однако, является факультативным, и в приведенном выше контексте компилятор не знает, что он не будет равен нулю, и ему необходимо принудительно развернуть. Поскольку инициализацией SKProductsRequest никогда не выработает ноль я не могу использовать

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

Тот путь, который я знаю, сделав заявление о currentProductRequest неявно без упаковки, как вар currentProductRequest: SKProductsRequest !. Это, однако, заставит компилятор думать, что currentProductRequest никогда не будет никчем, что может и не быть.

Я знаю, что принудительная разворачивание никогда не вызовет проблемы (в данном случае), но это кажется мне уродливым. Кто-нибудь знает, существует ли способ сообщить компилятору, что currentProductRequest не будет равен нулю и, таким образом, удалит принудительное развертывание.

ответ

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 
} 

Но это, вероятно, слишком убито.

+0

Это хорошее обходное решение. Если нет другого синтаксиса, спроектированного для того, что я попросил, я обязательно воспользуюсь этим подходом – Guus

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 
} 
+0

Спасибо за ответ, это решение уже было опубликовано Abizern (кроме перегрузки имени и использования self.). Но все равно спасибо! – Guus

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() 
} 
+0

Это прекрасное решение, мои идентификаторы, однако, изменяемы (по дизайну). Это, однако, решение многих других случаев: – Guus

Смежные вопросы