Estoy tratando de crear dinámicamente un class
tipo basado en instancias usando genéricos, sin embargo, me encuentro con dificultades con la introspección de clase.
Aquí están las preguntas:
- ¿Hay un Swift equivalente a Obj-C's
self.class
? - ¿Hay alguna manera de instanciar una clase usando el
AnyClass
resultado deNSClassFromString
? - ¿Hay alguna manera de obtener
AnyClass
o escribir información estrictamente de un parámetro genéricoT
? (Similar a latypeof(T)
sintaxis de C # )
introspection
swift
Erik
fuente
fuente
self.class
se convertiríaself.dynamicType.self
en la creencia Swift Iself.dynamicType.foo()
Respuestas:
Bueno, para uno, el equivalente rápido de
[NSString class]
es.self
(ver documentos de Metatype , aunque son bastante delgados).De hecho, ¡
NSString.class
ni siquiera funciona! Tienes que usarNSString.self
.Del mismo modo, con una clase rápida intenté ...
Hmm ... el error dice:
Me tomó un tiempo entender qué significa esto ... resulta que quiere que la clase tenga un
@required init()
Algunos de los documentos se refieren a esto como
.Type
, peroMyClass.Type
me da un error en el patio de recreo.fuente
.Type
o.Protocol
en declaración de variable, por ejemplolet myObject: MyObject.Type = MyObject.self
@
antesrequired
debe eliminarseAquí se explica cómo usarlo
NSClassFromString
. Tienes que conocer la superclase de lo que vas a terminar. Aquí hay un par de superclase-subclase que sabe cómo describirse paraprintln
:Observe el uso de la
@obj
sintaxis especial para dictar el nombre modificado de Objective-C de estas clases; eso es crucial, porque de lo contrario no conocemos la cadena unida que designa a cada clase.Ahora podemos usar
NSClassFromString
para hacer la clase Zork o la clase Zilk, porque sabemos que podemos escribirla como un NSObject y no bloquearnos más tarde:Y es reversible;
println(NSStringFromClass(anObject.dynamicType))
También funciona.Versión moderna:
fuente
@objc(ClassName)
bit. Sabía sobre el@objc
atributo, pero no porque también pudieras dar una pista sobre el nombre de la clase.as! NSObject.Type
en la primera línea yaClass.init()
en la segundaSi estoy leyendo la documentación correctamente, si maneja instancias y, por ejemplo, desea devolver una nueva instancia del mismo Tipo que el objeto que se le ha dado y el Tipo se puede construir con un init (), puede hacer:
Lo probé rápidamente con String:
que funcionó bien
fuente
dynamicType
funciona como esperaba allí. Sin embargo, no he podido comparar tipos. El gran uso real es con los genéricos, por lo que podría tener algo asíGeneric<T>
como dentroif T is Double {...}
. Parece que no es posible desafortunadamente.Defaultable
protocolo que funciona de manera similar a ladefault
palabra clave de C # y extensiones adecuadas para tipos comoString
yInt
. Al agregar la restricción genérica deT:Defaultable
, podría verificar si el argumento pasóis T.default()
.value is String.default()
... etc., lo que terminarías haciendo en suvalue is String
lugar.En Swift 3
es obsoleto.
En su lugar use:
fuente
Implementación rápida de tipos de comparación
NOTA: Tenga en cuenta que también funciona con protocolos que el objeto puede o no extender
fuente
Finalmente conseguí algo para trabajar. Es un poco vago, pero incluso la ruta NSClassFromString () no funcionó para mí ...
y bingo, "makeFoo" contiene una instancia de Foo.
La desventaja es que sus clases deben ser derivadas de FactoryObject y DEBEN tener el método de inicialización Obj-C + para que su clase se inserte automáticamente en el mapa de clase mediante la función global "mapClass".
fuente
Aquí hay otro ejemplo que muestra la implementación de la jerarquía de clases, similar a la respuesta aceptada, actualizada para la primera versión de Swift.
Imprime este resultado:
fuente
var x: NamedItem.Type
, si lo asignox = Folder.Type
,x()
devuelve un nuevoNamedItem
, no unFolder
. Esto hace que la técnica sea inútil para muchas aplicaciones. Considero que esto es un error .