Soy nuevo en la programación de Mac / iPhone y Objective-C. En C # y Java tenemos "genéricos", clases de colección cuyos miembros solo pueden ser del tipo declarado. Por ejemplo, en C #
Dictionary<int, MyCustomObject>
solo puede contener claves que son enteros y valores que son de tipo MyCustomObject. ¿Existe un mecanismo similar en Objective-C?
Respuestas:
En Xcode 7, Apple ha introducido 'Lightweight Generics' en Objective-C. En Objective-C, generarán advertencias del compilador si hay una falta de coincidencia de tipos.
Y en el código Swift, producirán un error de compilación:
Los Genéricos Ligeros están diseñados para usarse con NSArray, NSDictionary y NSSet, pero también puede agregarlos a sus propias clases:
Objective-C se comportará como antes con las advertencias del compilador.
pero Swift ignorará por completo la información genérica. (Ya no es cierto en Swift 3+.)
Interactuando con las API de Objective-C
fuente
MyClass <Foo: id<Bar>>
, su código Swift asumirá que los valores son el tipo de su restricción, lo que le brinda algo con lo que trabajar. Sin embargo, las subclases especializadas deMyClass
tendrían sus tipos especializados ignorados (se verá efectivamente lo mismo que un genéricoMyClass
). Ver github.com/bgerstle/LightweightGenericsExampleNo, no hay genéricos en Objective-C a menos que desee utilizar plantillas de C ++ en sus propias clases de colección personalizadas (lo cual desaconsejo encarecidamente).
Objective-C tiene la tipificación dinámica como una característica, lo que significa que al tiempo de ejecución no le importa el tipo de objeto, ya que todos los objetos pueden recibir mensajes. Cuando agrega un objeto a una colección integrada, solo se tratan como si fueran de tipo
id
. Pero no se preocupe, solo envíe mensajes a esos objetos como de costumbre; funcionará bien (a menos que, por supuesto, uno o más de los objetos de la colección no respondan al mensaje que está enviando) .Se necesitan genéricos en lenguajes como Java y C # porque son lenguajes fuertes y de tipo estático. Juego de pelota totalmente diferente a la característica de tipeo dinámico de Objective-C.
fuente
No, pero para que quede más claro, puede comentarlo con el tipo de objeto que desea almacenar, lo he visto algunas veces cuando necesita escribir algo en Java 1.4 hoy en día), por ejemplo:
o
fuente
No hay genéricos en Objective-C.
De los documentos
fuente
Apple ha agregado genéricos a ObjC en XCode 7:
ver aquí: https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html#//apple_ref/doc/uid/TP40014216-CH6-ID61
fuente
Esto fue lanzado en Xcode 7 (¡finalmente!)
Tenga en cuenta que en el código del Objetivo C, es solo una verificación en tiempo de compilación; no habrá ningún error en tiempo de ejecución solo por colocar el tipo incorrecto en una colección o asignarlo a una propiedad escrita.
Declarar:
Utilizar:
Ten cuidado con esos
*
s.fuente
Las matrices NSA genéricas se pueden realizar subclasificando
NSArray
y redefiniendo todos los métodos proporcionados con métodos más restrictivos. Por ejemplo,tendría que ser redefinido en
como
para que un NSArray contenga solo NSStrings.
La subclase creada se puede usar como un reemplazo directo y trae muchas características útiles: advertencias del compilador, acceso a la propiedad, mejor creación de código y finalización en Xcode. Todas estas son características de tiempo de compilación, no hay necesidad de redefinir la implementación real; los métodos de NSArray aún se pueden usar.
Es posible automatizar esto y reducirlo a solo dos declaraciones, lo que lo acerca a los idiomas que admiten genéricos. Creé una automatización con WMGenericCollection , donde las plantillas se proporcionan como Macros de preprocesador C.
Después de importar el archivo de encabezado que contiene la macro, puede crear un NSArray genérico con dos declaraciones: una para la interfaz y otra para la implementación. Solo necesita proporcionar el tipo de datos que desea almacenar y los nombres de sus subclases. WMGenericCollection proporciona tales plantillas para
NSArray
,NSDictionary
yNSSet
, así como sus contrapartes mutables.Un ejemplo:
List<int>
podría realizarse mediante una clase personalizada llamadaNumberArray
, que se crea con la siguiente instrucción:Una vez que haya creado
NumberArray
, puede usarlo en todas partes en su proyecto. Carece de la sintaxis de<int>
, pero puede elegir su propio esquema de nombres para etiquetarlos como clases como plantillas.fuente
Echa un vistazo a:
https://github.com/tomersh/Objective-C-Generics
Parece ser una especie de genéricos de los pobres, al reutilizar el mecanismo de verificación del protocolo.
fuente
Ahora los sueños se hacen realidad: hay genéricos en Objective-C desde hoy (gracias, WWDC). No es una broma, en la página oficial de Swift:
Y una imagen que prueba esto:
fuente
Solo quiero saltar aquí. He escrito una publicación de blog aquí sobre Genéricos.
Lo que quiero contribuir es que los genéricos se pueden agregar a cualquier clase , no solo a las clases de colección como indica Apple.
Luego he agregado con éxito a una variedad de clases, ya que funcionan exactamente igual que las colecciones de Apple. es decir. comprobación del tiempo de compilación, finalización del código, habilitación para la eliminación de moldes, etc.
Disfrutar.
fuente
Las clases de Colecciones proporcionadas por los marcos de Apple y GNUStep son semi-genéricas porque suponen que se les dan objetos, algunos que se pueden ordenar y otros que responden a ciertos mensajes. Para primitivas como flotantes, ints, etc., toda la estructura de los arreglos en C está intacta y se puede usar, y hay objetos de envoltura especiales para usar en las clases de colección general (por ejemplo, NSNumber). Además, una clase de Colección puede subclasificarse (o modificarse específicamente a través de categorías) para aceptar objetos de cualquier tipo, pero debe escribir todo el código de manejo de tipos usted mismo. Los mensajes pueden enviarse a cualquier objeto, pero deberían volverse nulos si no es apropiado para el objeto, o el mensaje debe reenviarse a un objeto apropiado. Los errores de tipo verdadero deben detectarse en tiempo de compilación, no en tiempo de ejecución. En tiempo de ejecución deben ser manejados o ignorados. Finalmente, Objc proporciona funciones de reflexión en tiempo de ejecución para manejar casos difíciles y la respuesta de mensajes, el tipo específico y los servicios se pueden verificar en un objeto antes de enviar un mensaje o colocarlo en una colección inapropiada. Tenga en cuenta que bibliotecas y marcos dispares adoptan diferentes convenciones sobre cómo se comportan sus objetos cuando envían mensajes para los que no tienen respuestas de código, por lo que RTFM. Además de los programas de juguete y las compilaciones de depuración, la mayoría de los programas no deberían tener que bloquearse a menos que realmente se arruinen e intenten escribir datos incorrectos en la memoria o el disco, realicen operaciones ilegales (por ejemplo, divídalo por cero, pero también puede atraparlo) o acceder recursos del sistema fuera de límites. El dinamismo y el tiempo de ejecución de Objective-C permiten que las cosas fallen con gracia y deben integrarse en su código. (SUGERENCIA) si tiene problemas con la genérica en sus funciones, prueba alguna especificidad. Escriba las funciones con tipos específicos y deje que el tiempo de ejecución seleccione (¡por eso se llaman selectores!) La función miembro apropiada en tiempo de ejecución.
fuente