W dokumentacji firmy Apple dotyczącej interakcji z interfejsami API języka C opisują sposób, w jaki NS_ENUM
wyliczenia w stylu C ze znacznikami są importowane jako wyliczenia Swift. Ma to sens, a ponieważ wyliczenia w języku Swift są łatwo dostarczane jako enum
typ wartości, łatwo jest zobaczyć, jak utworzyć własne.
W dalszej części jest to napisane o NS_OPTIONS
oznaczonych opcjach w stylu C:
Swift importuje również opcje oznaczone
NS_OPTIONS
makrem. Podczas gdy opcje zachowują się podobnie do zaimportowanych wyliczeń, opcje mogą również obsługiwać niektóre operacje bitowe, takie jak&
,|
i~
. W Objective-C reprezentujesz pusty zestaw opcji ze stałą zerową (0
). W języku Swift służynil
do reprezentowania braku jakichkolwiek opcji.
Biorąc pod uwagę, że options
w języku Swift nie ma typu wartości, w jaki sposób możemy utworzyć zmienną opcji w stylu C do pracy?
źródło
RawOptionsSetType
: nshipster.com/rawoptionsettypeOdpowiedzi:
Swift 3.0
Prawie identyczny z Swift 2.0. Nazwa OptionSetType została zmieniona na OptionSet i zgodnie z konwencją wyliczenia są zapisywane małymi literami.
Zamiast oferować
none
opcję, zaleceniem Swift 3 jest po prostu użycie pustego literału tablicy:Inne zastosowanie:
Swift 2.0
W Swift 2.0 rozszerzenia protokołów zajmują się większością standardowych elementów, które są teraz importowane jako struktura zgodna z
OptionSetType
. (RawOptionSetType
zniknął od Swift 2 beta 2.) Deklaracja jest znacznie prostsza:Teraz możemy używać semantyki opartej na zbiorach z
MyOptions
:Swift 1.2
Patrząc na opcjach Objective-C, które zostały przywiezione przez SWIFT (
UIViewAutoresizing
na przykład), możemy zobaczyć, że opcje są zadeklarowane jakostruct
zgodnym z protokołemRawOptionSetType
, który z kolei jest zgodny z_RawOptionSetType
,Equatable
,RawRepresentable
,BitwiseOperationsType
, iNilLiteralConvertible
. Możemy stworzyć własne w ten sposób:Teraz możemy traktować ten nowy zestaw opcji
MyOptions
, tak jak opisano w dokumentacji Apple: możesz użyćenum
składni podobnej do -jak:Zachowuje się również tak, jakbyśmy oczekiwali, że opcje będą się zachowywać:
Zbudowałem generator do tworzenia zestawu opcji Swift bez konieczności znajdowania / zastępowania.
Najnowsze: Modyfikacje do Swift 1.1 beta 3.
źródło
value
plikUInt32
. Nie musisz także definiować żadnej funkcji, odpowiednie funkcje są już zdefiniowane dlaRawOptionSet
s (np.func |<T : RawOptionSet>(a: T, b: T) -> T
)UInt
? U mnie działa dobrze.enum CollisionTypes: UInt32 { case Player = 1 case Wall = 2 case Star = 4 case Vortex = 8 case Finish = 16 }
Xcode 6.1 Beta 2 wprowadził pewne zmiany w
RawOptionSetType
protokole (zobacz ten wpis na blogu Airspeedvelocity i informacje o wydaniu Apple ).Na podstawie przykładu Nate Cooks tutaj jest zaktualizowane rozwiązanie. Możesz zdefiniować swój własny zestaw opcji w następujący sposób:
Można go następnie użyć w następujący sposób do zdefiniowania zmiennych:
I tak, aby przetestować bity:
źródło
Przykład Swift 2.0 z dokumentacji:
Znajdziesz go tutaj
źródło
W Swift 2 (obecnie beta jako część wersji beta Xcode 7)
NS_OPTIONS
typy-style są importowane jako podtypy nowegoOptionSetType
typu. Dzięki nowej funkcji Protocol Extensions i sposobowiOptionSetType
implementacji w standardowej bibliotece możesz zadeklarować własne typy, które rozszerzająOptionsSetType
i uzyskują te same funkcje i metody, które zostały zaimportowaneNS_OPTIONS
otrzymują typy.Ale te funkcje nie są już oparte na bitowych operatorach arytmetycznych. To, że praca z zestawem niewyłącznych opcji boolowskich w C wymaga maskowania i kręcenia bitów w polu, jest szczegółem implementacji. Tak naprawdę zestaw opcji to zestaw ... zbiór unikalnych przedmiotów. Więc
OptionsSetType
pobiera wszystkie metody zSetAlgebraType
protokołu, takie jak tworzenie ze składni literału tablicowego, zapytania, takie jakcontains
maskowanieintersection
itp. ( Koniec z koniecznością pamiętania, którego zabawnego znaku użyć dla którego testu członkostwa!)źródło
źródło
Jeśli nie potrzebujesz współdziałać z Objective-C i po prostu potrzebujesz powierzchniowej semantyki masek bitowych w Swift, napisałem prostą „bibliotekę” o nazwie BitwiseOptions, która może to zrobić za pomocą zwykłych wyliczeń w języku Swift, np .:
i tak dalej. Żadne rzeczywiste bity nie są tutaj odwracane. Są to operacje na ustawieniach nieprzezroczystych wartości. Możesz znaleźć sedno tutaj .
źródło
Jak już wspomniał Rickster, możesz użyć OptionSetType w Swift 2.0. Typy NS_OPTIONS są importowane jako zgodne z
OptionSetType
protokołem, co przedstawia interfejs podobny do zestawu dla opcji:Daje ci taki sposób pracy:
źródło
Jeśli jedyną funkcjonalnością, której potrzebujemy, jest sposób łączenia opcji
|
i sprawdzania, czy połączone opcje zawierają konkretną opcję z&
alternatywą dla odpowiedzi Nate Cooka, może to być:Utwórz opcje
protocol
i przeciąż|
i&
:Teraz możemy tworzyć struktury opcji w prostszy sposób:
Można ich używać w następujący sposób:
źródło
Po prostu zamieszczam dodatkowy przykład dla każdego, kto zastanawiał się, czy można połączyć opcje złożone. Możesz i łączą się tak, jak można by się spodziewać, jeśli jesteś przyzwyczajony do starych, dobrych pól bitowych:
Spłaszcza zestaw
[.AB, .X]
do[.A, .B, .X]
(przynajmniej semantycznie):źródło
Nikt inny o tym nie wspomniał - i trochę się pomyliłem po kilku majstrach - ale Swift Set wydaje się działać całkiem dobrze.
Jeśli pomyślimy (może na diagramie Venna?) O tym, co właściwie reprezentuje maska bitowa, jest to prawdopodobnie pusty zbiór.
Oczywiście, podchodząc do problemu od pierwszych zasad, tracimy wygodę operatorów bitowych, ale zyskujemy potężne metody oparte na zbiorach, które poprawiają czytelność.
Oto moje majsterkowanie na przykład:
Uważam to za przyjemne, ponieważ czuję, że wynika to z podejścia do problemu opartego na podstawowych zasadach - podobnie jak w przypadku Swift - zamiast próby dostosowania rozwiązań w stylu C.
Chciałbym również usłyszeć kilka przypadków użycia Obj-C, które podważałyby ten inny paradygmat, w którym nieprzetworzone wartości całkowite nadal wykazują zalety.
źródło
W celu uniknięcia twarde kodowania pozycji bitowych, co jest nieuniknione przy korzystaniu
(1 << 0)
,(1 << 1)
,(1 << 15)
itd., A nawet gorzej1
,2
,16384
itd. Lub jakąś odmianę szesnastkowy, można najpierw definiuje bity wenum
, pozwól powiedział enum zrobić bit porządkowej obliczenia:źródło
Używam następujących potrzebuję obu wartości, które mogę uzyskać, rawValue do indeksowania tablic i wartości dla flag.
A jeśli potrzeba więcej, po prostu dodaj obliczoną właściwość.
źródło
re: Tworzenie piaskownicy i zakładek przy użyciu zestawów opcji z kilkoma opcjami
rozwiązanie polegające na konieczności łączenia opcji dla kreacji, przydatne, gdy nie wszystkie opcje wykluczają się wzajemnie.
źródło
Odpowiedź Nate'a jest dobra, ale zrobiłbym to samodzielnie, na przykład:
źródło
Użyj typu zestawu opcji w szybkim 3 użyciu
OptionSet
źródło