Согласно pre-release Swift 2 documentation есть теперь #available
ключевое слово, которое может быть использовано с помощью оператора if let
или guard
для проверки наличия API. Это приводит следующий пример:Swift #available ключевого слова против respondsToSelector
let locationManager = CLLocationManager()
if #available(iOS 8.0, OSX 10.10, *) {
locationManager.requestWhenInUseAuthorization()
}
Или
let locationManager = CLLocationManager()
guard #available(iOS 8.0, OSX 10.10, *) else { return }
locationManager.requestWhenInUseAuthorization()
Какой он (документ) утверждает, является эквивалентом следующего кода Objective-C:
if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)]) {
// Method is available for use.
} else {
// Method is not available.
}
Очевидно respondsToSelector:
работает только на подклассах NSObject
, тогда как ключевое слово #available
будет работать даже для «чистого» кода Swift, поэтому я ценю это преимущество.
Однако, начиная с разработки iOS, мне всегда приходилось полагать, что лучшей практикой для этой ситуации является обнаружение присутствия API, а не полагаться на версию, которую она представила.
В качестве более конкретного примера я думаю, когда Apple представила firstObject
на NSArray
в iOS 7, но задним числом сделала его доступным для iOS 4 (где она была доступна, но была закрыта). Любой код с использованием respondsToSelector:
работал бы на iOS < 7, но, очевидно, проверка версии не удалась.
Есть ли какие-либо преимущества для перехода на ключевое слово #available
, которое я пропустил?
@holex Они оба являются решениями времени исполнения. – Sulthan
Я думаю, причина в том, что Swift не позволяет нам создавать ссылки на функции или методы (кроме текстовых), и это тоже опасно. Использование любого вида 'responsesToSelector' в Swift выглядит уродливо, потому что вы должны указать имя метода как строку (также в условном названии метода Obj-C) :) Я не уверен, что' # available' является улучшением, но это будет способствовать согласованности кода, потому что рано или поздно появятся скоростные рамки Swift. С другой стороны, проверка версии доступна только для системной версии, поэтому для внешних библиотек вам все равно придется использовать проверку выбора. – Sulthan
Библиотеки @Sulthan External (Swift 2) могут аннотировать свой собственный API с ключевым словом '@ availability'. В качестве побочной заметки я не уверен в совместимости с использованием 'if #available ...' с помощью методов Objective-C, аннотированных с помощью' NS_AVAILABLE'. Я полностью согласен с тем, что 'responsesToSelector:' имеет свои проблемы даже в Objective-C, и необходимость указывать селектор как строку в Swift просто ужасна. Я все по-хорошему, но #доступный (кажется мне) как побочный шаг, а не шаг вперед. –