Czy Swift wspiera refleksję? np. czy istnieje coś takiego jak valueForKeyPath:
i setValue:forKeyPath:
dla obiektów Swift?
Właściwie to ma w ogóle dynamiczny system typów, coś w rodzaju obj.class
Objective-C?
ios
reflection
swift
Khanh Nguyen
źródło
źródło
Odpowiedzi:
Wygląda na to, że jest początek wsparcia dla refleksji:
Z istoty mchambers, tutaj: https://gist.github.com/mchambers/fb9da554898dae3e54f2
źródło
Mirror
faktycznie cytuje to słowoIDE
kilka razy._stdlib_getTypeName
możesz pomóc.Jeśli klasa się rozszerza
NSObject
, wtedy cała introspekcja i dynamizm Objective-C działają. To zawiera:Jedną z wad tej funkcji jest obsługa opcjonalnych typów wartości języka Swift. Na przykład właściwości Int mogą być wyliczane i modyfikowane, ale Int? właściwości nie mogą. Typy opcjonalne można wyliczyć częściowo za pomocą refleksu / MirrorType, ale nadal nie są one modyfikowane.
Jeśli klasa się nie rozszerza
NSObject
, działa tylko nowe, bardzo ograniczone (i w toku?) Odbicie (patrz odbicie / MirrorType), które dodaje ograniczoną możliwość zadawania instancji pytania o jej klasę i właściwości, ale nie ma żadnych dodatkowych funkcji powyżej .Jeśli nie rozszerzasz NSObject lub używasz dyrektywy „@objc”, Swift domyślnie korzysta z wysyłek statycznych i vtable. Jest to jednak szybsze, jednak w przypadku braku maszyny wirtualnej nie pozwala na przechwycenie metody w czasie wykonywania. To przechwycenie jest podstawową częścią Cocoa i jest wymagane dla następujących typów funkcji:
Dlatego zaleca się stosowanie klas w aplikacjach Cocoa / CocoaTouch zaimplementowanych w Swift:
Podsumowanie:
Dane referencyjne: obciążenie związane z wykonywaniem wywołań metod:
(rzeczywista wydajność zależy od sprzętu, ale wskaźniki pozostaną podobne).
Ponadto atrybut dynamiczny pozwala nam wyraźnie poinstruować Swift, że metoda powinna używać dynamicznego wysyłania, a zatem będzie obsługiwać przechwytywanie.
źródło
Dokumentacja mówi o dynamicznym systemie typów, głównie o
Type
idynamicType
Zobacz Typ metatypu (w odwołaniu do języka)
Przykład:
Teraz zakładając, że się
TestObject
rozciągaNSObject
Obecnie nie ma wdrożonej refleksji.
EDYCJA: Najwyraźniej się myliłem, zobacz odpowiedź Stevexa. Istnieje pewne proste odbicie tylko do odczytu dla wbudowanych właściwości, prawdopodobnie w celu umożliwienia środowiskom IDE inspekcji zawartości obiektu.
źródło
Wygląda na to, że interfejs API Swift refleksji nie jest obecnie priorytetem dla Apple. Ale oprócz odpowiedzi @stevex jest jeszcze jedna funkcja w bibliotece standardowej, która pomaga.
Od wersji beta 6
_stdlib_getTypeName
pobiera zniekształconą nazwę typu zmiennej. Wklej to do pustego placu zabaw:Wynik to:
Wpis na blogu Ewana Swicka pomaga rozszyfrować te ciągi:
np.
_TtSi
oznacza wewnętrznyInt
typ Swift .Mike Ash ma świetny wpis na blogu na ten sam temat .
źródło
Możesz zamiast tego rozważyć użycie metody toString () . Jest publiczny i działa tak samo jak _stdlib_getTypeName () z tą różnicą, że działa również na AnyClass , np. W Playground enter
źródło
Brak
reflect
słowa kluczowego w Swift 5, teraz możesz go użyćźródło
json
deserializacji