Я пытаюсь динамически создать class
тип на основе экземпляра с использованием универсальных шаблонов, однако у меня возникают трудности с самоанализом класса.
Вот вопросы:
- Есть ли Swift-эквивалент Obj-C
self.class
? - Есть ли способ создать экземпляр класса, используя
AnyClass
результатNSClassFromString
? - Есть ли способ получить
AnyClass
или иным образом ввести информацию строго из общего параметраT
? (Аналогичноtypeof(T)
синтаксису C # )
introspection
swift
Erik
источник
источник
self.class
превратитсяself.dynamicType.self
в Swift I, верю,self.dynamicType.foo()
Ответы:
Ну, во- первых , Swift эквивалент
[NSString class]
is.self
(см. Документацию Metatype , хотя они довольно тонкие).На самом деле
NSString.class
даже не работает! Вы должны использоватьNSString.self
.Точно так же с быстрым классом я пробовал ...
Хм… ошибка говорит:
Мне потребовалось время, чтобы понять, что это значит ... оказывается, он хочет, чтобы в классе был
@required init()
В некоторых документах это называется
.Type
, ноMyClass.Type
выдает ошибку на игровой площадке.источник
.Type
или.Protocol
в объявлении переменной, напримерlet myObject: MyObject.Type = MyObject.self
@
передrequired
следует удалитьВот как пользоваться
NSClassFromString
. Вы должны знать суперкласс того, что у вас получится. Вот пара суперкласс-подкласс, которые знают, как себя описатьprintln
:Обратите внимание на использование специального
@obj
синтаксиса для указания измененных имен Objective-C этих классов; это очень важно, потому что иначе мы не знаем измененную строку, обозначающую каждый класс.Теперь мы можем использовать
NSClassFromString
для создания класса Zork или класса Zilk, потому что мы знаем, что можем ввести его как NSObject и избежать сбоя позже:И это обратимо;
println(NSStringFromClass(anObject.dynamicType))
тоже работает.Современная версия:
источник
@objc(ClassName)
бит. Я знал об@objc
атрибуте, но не знал, что вы также можете намекнуть на имя класса.as! NSObject.Type
в первой строке иaClass.init()
во второйЕсли я правильно читаю документацию, если вы имеете дело с экземплярами и, например, хотите вернуть новый экземпляр того же типа, что и объект, который вам был предоставлен, и тип может быть создан с помощью init (), вы можете сделать:
Я быстро протестировал это с помощью String:
который работал нормально.
источник
dynamicType
работает, как я ожидал. Однако мне не удалось сравнить типы. По-настоящему широко используются дженерики, так что у меня может быть что-то вродеGeneric<T>
и внутриif T is Double {...}
. Кажется, к сожалению, это невозможно.Defaultable
протокол, который работает аналогичноdefault
ключевому слову C # , и соответствующие расширения для таких типов, какString
иInt
. Добавив общее ограничениеT:Defaultable
, я мог проверить, передан ли аргументis T.default()
.value is String.default()
... и т.д., что вы бы просто сделалиvalue is String
вместо этого.В быстром 3
устарела.
Вместо этого используйте:
источник
Быстрая реализация сравнения типов
ПРИМЕЧАНИЕ: обратите внимание, что он также работает с протоколами, которые объект может или не может расширять.
источник
Наконец-то есть над чем работать. Это немного лениво, но даже маршрут NSClassFromString () у меня не работал ...
и бинго, makeFoo содержит экземпляр Foo.
Обратной стороной является то, что ваши классы должны быть производными от FactoryObject, и они ДОЛЖНЫ иметь метод инициализации Obj-C +, чтобы ваш класс автоматически вставлялся в карту классов глобальной функцией mapClass.
источник
Вот еще один пример, показывающий реализацию иерархии классов, аналогичную принятому ответу, обновленному для первого выпуска Swift.
Распечатывает этот результат:
источник
var x: NamedItem.Type
если я назначу егоx = Folder.Type
, тоx()
вернет новыйNamedItem
, а не файлFolder
. Это делает метод бесполезным для многих приложений. Считаю это ошибкой .