En la documentación de Apple sobre la interacción con las API de C, describen la forma NS_ENUM
enumeraciones de estilo C marcadas se importan como enumeraciones Swift. Esto tiene sentido, y dado que las enumeraciones en Swift se proporcionan fácilmente como el enum
tipo de valor, es fácil ver cómo crear el nuestro.
Más abajo, dice esto sobre NS_OPTIONS
opciones de estilo C marcadas:
Swift también importa opciones marcadas con la
NS_OPTIONS
macro. Mientras que las opciones se comportan de manera similar a las enumeraciones importados, las opciones también pueden apoyar algunas operaciones bit a bit, tales como&
,|
, y~
. En Objective-C, representa un conjunto de opciones vacío con la constante cero (0
). En Swift, usenil
para representar la ausencia de opciones.
Dado que no hay un options
tipo de valor en Swift, ¿cómo podemos crear una variable de opciones de estilo C para trabajar?
fuente
RawOptionsSetType
: nshipster.com/rawoptionsettypeRespuestas:
Swift 3.0
Casi idéntico a Swift 2.0. OptionSetType se renombró a OptionSet y las enumeraciones se escriben en minúsculas por convención.
En lugar de proporcionar una
none
opción, la recomendación de Swift 3 es simplemente usar un literal de matriz vacío:Otro uso:
Swift 2.0
En Swift 2.0, las extensiones de protocolo se encargan de la mayoría de las repeticiones, que ahora se importan como una estructura que se ajusta a ellas
OptionSetType
. (RawOptionSetType
ha desaparecido a partir de Swift 2 beta 2.) La declaración es mucho más simple:Ahora podemos usar la semántica basada en conjuntos con
MyOptions
:Swift 1.2
En cuanto a las opciones de Objective-C que se importaron por Swift (
UIViewAutoresizing
por ejemplo), podemos ver que las opciones se declaran como unastruct
que cumpla con el protocoloRawOptionSetType
, que cumple en turno para_RawOptionSetType
,Equatable
,RawRepresentable
,BitwiseOperationsType
, yNilLiteralConvertible
. Podemos crear el nuestro así:Ahora podemos tratar este nuevo conjunto de opciones
MyOptions
, tal como se describe en la documentación de Apple: puede usar unaenum
sintaxis similar:Y también se comporta como esperaríamos que se comporten las opciones:
He construido un generador para crear un conjunto de opciones Swift sin todo el buscar / reemplazar.
Último: Modificaciones para Swift 1.1 beta 3.
fuente
value
unUInt32
. Tampoco necesita definir ninguna de las funciones, las funciones relevantes ya están definidas paraRawOptionSet
s (por ejemplofunc |<T : RawOptionSet>(a: T, b: T) -> T
)UInt
? Esta trabajando bien para mi.enum CollisionTypes: UInt32 { case Player = 1 case Wall = 2 case Star = 4 case Vortex = 8 case Finish = 16 }
Xcode 6.1 Beta 2 trajo algunos cambios al
RawOptionSetType
protocolo (consulte esta entrada de blog de Airspeedvelocity y las notas de la versión de Apple ).Basado en el ejemplo de Nate Cooks, aquí hay una solución actualizada. Puede definir su propio conjunto de opciones de esta manera:
Luego se puede usar así para definir variables:
Y así para probar bits:
fuente
Ejemplo de Swift 2.0 de la documentación:
Lo puedes encontrar aqui
fuente
En Swift 2 (actualmente beta como parte de Xcode 7 beta), los
NS_OPTIONS
tipos de estilo se importan como subtipos del nuevoOptionSetType
tipo. Y gracias a la nueva característica Extensiones de protocolo y la forma en queOptionSetType
se implementa en la biblioteca estándar, puede declarar sus propios tipos que se extiendenOptionsSetType
y obtienen las mismas funciones y métodos que losNS_OPTIONS
tipos de estilo importados .Pero esas funciones ya no se basan en operadores aritméticos bit a bit. Que trabajar con un conjunto de opciones booleanas no exclusivas en C requiere enmascarar y girar bits en un campo es un detalle de implementación. Realmente, un conjunto de opciones es un conjunto ... una colección de artículos únicos. Por lo tanto,
OptionsSetType
obtiene todos los métodos delSetAlgebraType
protocolo, como la creación de sintaxis literal de matriz, consultas comocontains
, enmascaramientointersection
, etc. (¡No más tener que recordar qué personaje divertido usar para qué prueba de membresía!)fuente
fuente
Si no necesita interoperar con Objective-C y solo desea la semántica de superficie de las máscaras de bits en Swift, he escrito una simple "biblioteca" llamada BitwiseOptions que puede hacer esto con enumeraciones regulares de Swift, por ejemplo:
y así. Aquí no se están volteando partes reales. Estas son operaciones establecidas en valores opacos. Puedes encontrar la esencia aquí .
fuente
Como Rickster ya mencionó, puede usar OptionSetType en Swift 2.0. Los tipos NS_OPTIONS se importan conforme al
OptionSetType
protocolo, que presenta una interfaz similar a un conjunto para las opciones:Te ofrece esta forma de trabajar:
fuente
Si la única funcionalidad que necesitamos es una forma de combinar opciones
|
y verificar si las opciones combinadas contienen una opción particular con&
una alternativa a la respuesta de Nate Cook podría ser esta:Crea una opción
protocol
y sobrecarga|
y&
:Ahora podemos crear estructuras de opciones más simplemente así:
Se pueden usar de la siguiente manera:
fuente
Solo publico un ejemplo adicional para cualquier persona que se preguntara si podría combinar opciones compuestas. Puede, y se combinan como es de esperar si está acostumbrado a los viejos campos de bits:
Se aplana el conjunto
[.AB, .X]
en[.A, .B, .X]
(al menos semánticamente):fuente
Nadie más lo ha mencionado, y me equivoqué después de algunos retoques, pero un Swift Set parece funcionar bastante bien.
Si pensamos (¿tal vez en un diagrama de Venn?) Acerca de lo que realmente representa una máscara de bits, es un conjunto posiblemente vacío.
Por supuesto, al abordar el problema desde los primeros principios, perdemos la comodidad de los operadores bit a bit, pero obtenemos métodos poderosos basados en conjuntos que mejoran la legibilidad.
Aquí está mi retoque, por ejemplo:
Encuentro esto agradable porque siento que proviene de un enfoque de primeros principios para el problema, al igual que Swift, en lugar de tratar de adaptar soluciones de estilo C.
También me gustaría escuchar algunos casos de uso de Obj-C que desafiarían este paradigma diferente, donde los valores brutos enteros aún muestran mérito.
fuente
Con el fin de evitar la codificación duro las posiciones de bit, que es inevitable cuando se utilizan
(1 << 0)
,(1 << 1)
,(1 << 15)
etc., o incluso peor1
,2
,16384
etc., o alguna variación hexadecimal, se podría primero define los bits en unaenum
, entonces que dijo enum hacer el cálculo ordinal bits:fuente
Utilizo lo siguiente. Necesito los dos valores que puedo obtener, rawValue para indexar matrices y valor para flags.
Y si uno necesita más, simplemente agregue una propiedad calculada.
fuente
re: Sandbox y creaciones de marcadores usando conjuntos de opciones con varias opciones
solución a la necesidad de combinar opciones para creaciones, útil cuando no todas las opciones son mutuamente excluyentes.
fuente
La respuesta de Nate es buena, pero lo haría DIY, así:
fuente
Use un tipo de conjunto de opciones, en uso rápido 3
OptionSet
fuente