2016-03-18 5 views
0

Возьмите для этих двух методов в NSCalander классе:Опции Enum Эквивалент в Swift

component(unit: NSCalanderUnit, fromDate: NSDate) -> Int 
components(unitFlags: NSCalanderUnit, fromDate: NSDate) -> NSDateComponents 

В первом методе мы называем его с одним NSCalanderUnit:

someCalander.component(unit: .Minute, fromDate: NSDate()) 

Во втором методе сигнатура типа предполагает, что мы даем ей один NSCalanderUnit, но на самом деле для обеспечения более чем одного устройства нам нужно будет вызвать метод следующим образом:

components(unitFlags: [.Hour, .Day], fromDate: NSDate) 

Теперь я понимаю причину этого говоря, что это требует всего лишь NSCalanderUnit в отличие от [NSCalanderUnit] является то, что структура какао была написана в Objective-C, а затем ликвидирует код быстрым. В Objective-C NSCalanderUnit является перечнем NS_Option «perum». В которой мы используем битовую маску для объединения нескольких флагов (или «опций»), мы используем побитовый оператор |.

Так что мой вопрос:

Почему мы называем его в квадратных скобках вместо вызова его следующим образом:

components(unitFlags: .Hour | .Day, fromDate: NSDate) 

ответ

2

Это известно как набор опций, автоматически соединенный с объективом C NS_OPTION. Они фактически являются более безопасным для типа способом обращения с типом перечисления, в котором можно выбрать несколько вариантов. В Swift эти значения не обрабатываются как бит-маски (как в Objective C, и поэтому почему оператор | здесь недействителен), а скорее как различные значения перечисления. Набор параметров эффективно действует как набор этого перечисления, предоставляя безопасный мост типа с эквивалентной функциональностью.

Apple, определяет детали их реализации здесь: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html

1

Почему мы называем его с массивом буквальным, когда он не считаются массивом

Это не массив. Это больше похоже на набор. На самом деле это набор опций.

+0

Посмотрите мою книгу, если вам не потрудились прочитать документацию Apple: http://www.apeth.com/swiftBook/ch04.html#SECoptionsSets – matt

1

Это OptionSetType. Это то, что вы получаете, когда вы импортировать NS_ OPTIONS перечисления из C, и вы можете создать свой собственный в Swift, используя стиль, показанный на странице связаны Документах

struct PackagingOptions : OptionSetType { 
    let rawValue: Int 
    init(rawValue: Int) { self.rawValue = rawValue } 

    static let Box = PackagingOptions(rawValue: 1) 
    static let Carton = PackagingOptions(rawValue: 2) 
    static let Bag = PackagingOptions(rawValue: 4) 
    static let Satchel = PackagingOptions(rawValue: 8) 
    static let BoxOrBag: PackagingOptions = [Box, Bag] 
    static let BoxOrCartonOrBag: PackagingOptions = [Box, Carton, Bag] 
} 

Почему это так? Такие типы, как они используются в API, концептуально наборы: группировки одного или нескольких уникальных значений. То, что мы создаем их как битовые поля в C, - это просто деталь реализации. Получение побитовых операций для всех, кроме самых простых наборов конструкций и запросов, легко ошибиться, и даже когда это правильно, оно многословно и не читается четко - нужно понять, что куча ORs и AND означает «if это любые значения A, B или D, но не C или E ".

В противоположность этому, когда вы создаете или импортировать OptionSetType, Вы получаете автоматическую реализацию all the set operations, как contains и intersect и isEmpty. И вы можете использовать литерал типа set/array-style для построения значений, который более точно говорит: «Я хочу, чтобы компоненты« Hour и Day »вместо« Я хочу, чтобы какое-то целочисленное значение было побитовым ИЛИ любого Hour и Day ».

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