Estoy tratando de crear dinámicamente un classtipo 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
AnyClassresultado deNSClassFromString? - ¿Hay alguna manera de obtener
AnyClasso escribir información estrictamente de un parámetro genéricoT? (Similar a latypeof(T)sintaxis de C # )
introspection
swift
Erik
fuente
fuente

self.classse convertiríaself.dynamicType.selfen 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.classni 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.Typeme da un error en el patio de recreo.fuente
.Typeo.Protocolen declaración de variable, por ejemplolet myObject: MyObject.Type = MyObject.self@antesrequireddebe 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
@objsintaxis 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
NSClassFromStringpara 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@objcatributo, pero no porque también pudieras dar una pista sobre el nombre de la clase.as! NSObject.Typeen 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
dynamicTypefunciona 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.Defaultableprotocolo que funciona de manera similar a ladefaultpalabra clave de C # y extensiones adecuadas para tipos comoStringyInt. 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 Stringlugar.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 .