Lo que realmente me gusta de C# son las listas genéricas. Una lista que puede contener solo un tipo de objetos. ¿Hay algo así como una lista genérica en Cocoa/Objective-C? Por lo que solo sé NSArray
que tomará un puntero a cualquier objeto.¿Hay algo así como una lista genérica en Cocoa/Objective-C?
Respuesta
Querer esto en una aplicación de Cocoa a menudo es un signo de un diseño débil.
NSArray
es inmutable, por lo que no "tomará un puntero a ningún objeto" y presumiblemente ya contiene los objetos correctos cuando se le entregó. Lo que supongo que está más preocupado es un NSMutableArray
donde cree que otras partes de su código podrían agregar el tipo de objeto incorrecto. Pero eche un vistazo al cacao en sí mismo; es increíblemente raro exponer una matriz mutable como parte del diseño de una clase.
En cambio, por lo general, exponer una NSArray
y un par de métodos para la modificación de la matriz. Algo a lo largo de las líneas de:
@class Foo : NSObject
- (NSArray *)bars;
- (void)addBar:(Bar *)bar;
- (void)removeBar:(Bar *)bar;
@end
Esto generalmente se detiene objetos erróneos que se inserta simplemente por tener una advertencia del compilador, y luego, por supuesto, se puede añadir afirmaciones dentro -addBar:
y -removeBar:
si lo desea también.
Gran respuesta. Muchas gracias. Justo lo que tenía en mente. – TalkingCode
Además, si necesita operaciones más avanzadas, lea en -mutableArrayValueForKey: –
+1 "Querer esto es a menudo un signo de un diseño débil" –
Objective-C no es compatible con la programación genérica. Siempre puedes usar Objective-C++ y una lista STL.
NSArrays genéricos se pueden realizar por subclases NSArray
, y la redefinición de todos los métodos proporcionados por otros más restrictivas. Por ejemplo,
- (id)objectAtIndex:(NSUInteger)index
tendrían que ser redefinido en
@interface NSStringArray : NSArray
como
- (NSString *)objectAtIndex:(NSUInteger)index
para una NSArray a contener sólo NSStrings.
La subclase creada se puede utilizar como una gota en el reemplazo y trae muchas características útiles: las advertencias del compilador, acceso a la propiedad, una mejor creación de código y -Realizació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 sólo dos estados, lo que lo acerca a lenguajes que soportan los 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 cabecera que contiene la macro, se puede crear un NSArray genérico con dos estados: uno para la interfaz y uno para la aplicación. Solo necesita proporcionar el tipo de datos que desea almacenar y los nombres de sus subclases. WMGenericCollection proporciona tales plantillas para NSArray
, NSDictionary
y NSSet
, así como sus contrapartes mutables.
¡Gracias por publicar tu respuesta! Asegúrese de leer detenidamente [Preguntas frecuentes sobre autopromoción] (http://stackoverflow.com/faq#promotion). También tenga en cuenta que * se requiere * que publique un descargo de responsabilidad cada vez que se vincula a su propio sitio/producto. –
Gracias por señalar eso. No estaba seguro de cómo hacer esto o si se considera demasiado spam. En este momento estoy ocupado, pero revisaré las respuestas de acuerdo con las pautas en un par de horas. –
¡Excelente! Sus dos últimas respuestas son decentes, porque parecen abordar la pregunta, ha incluido buena información (no solo "vea este proyecto aquí" y una lista de características). Simplemente agregue la divulgación, y están bien. ¡gracias de nuevo! Ah, también; solo para tu información; tenga cuidado de publicar copias exactas de las respuestas; Estos parecen ser lo suficientemente buenos para sus preguntas, pero asegúrese de tratar de adaptar las respuestas a la pregunta específicamente. –
No, Objective-C no soporta actualmente escribiendo paramétrico para elementos de la colección.
Sin embargo, este tema es más complejo que la pregunta o las respuestas existentes admiten ..
Parametric-Typing para colecciones en Objective-C no sería lo mismo que Generics en C#/Java. Por ejemplo, es poco probable que alguna vez vea que Objective-C agrega la capacidad para asegurar que cada objeto agregado a una colección IS sea un tipo o subtipo NSArray. En cambio, Objective-C podría (y la OMI debería) tener la capacidad de asegurar que cada objeto en una colección CONFORMA en un protocolo/interfaz. (es decir, que implementa un conjunto de métodos requeridos)
¿Por qué?
Objective-C es un lenguaje basado en la compatibilidad de protocolo (interfaz), NO relaciones de subtipado. Es decir, los objetos son compatibles si tienen todos los métodos correctos, no miramos ni nos preocupamos por sus tipos reales. De hecho, mirar los tipos reales es una muy mala práctica en Obj-C y muy desalentada. Esta noción a veces se llama "Duck Typing", porque si grazna como un pato, es un pato. No nos importa si literalmente heredó de algún pato específico o no. Esto evita que sea ensillado por otra jerarquía de implementación. - El resultado es que mientras un objeto que sale de la lista tenga un método draw :: funciona, realmente no nos importa si es una subclase de algún objeto específico de JimmyDrawableBase.
Esto no solo hace que el código sea más reutilizable, sino que también alienta un tipo de descomposición del problema un poco diferente (¿más funcional?), Porque no puede confiar en objetos derivados de una clase base dada y tener un montón de su implementación de clase base forzada en ellos.
yo personalmente creo que sería agradable para el compilador Obj-C por reforzar los controles paramétricos de PROTOCOLO DE CONFORMIDAD * *. Es decir, para hacer un NSMutableArray que requiera que todos los objetos colocados en él se ajusten a un protocolo dado (es decir, que tengan un conjunto dado de métodos requeridos).
A veces, incluso esta comprobación de conformidad de protocolo más flexible es resistida por gente de programación dinámica, y por razones de sonido. Los programadores a menudo tienen una manera de especificar en exceso los requisitos de conformidad.
Por ejemplo, es posible que necesite una lista que contenga objetos que se ajusten al protocolo/interfaz NSArray, pero puede ACTUALMENTE llamar solo a dos de esos métodos. Esto es sobre-conformidad. Alguien que desea insertar un elemento compatible en su matriz se ve obligado a implementar una tonelada de métodos que no está llamando en realidad, al menos todavía (consulte a continuación).
Google Go intenta resolver este problema deduciendo compatibilidad estructural. Es decir, si llama a draw() sobre elementos que salen de una lista, entonces el compilador asegura que todo lo que entra en una lista contiene un método draw(). Si no contiene un método draw(), es un error de compilación colocarlo en la lista. Esto evita que el código simplemente cause el mismo error en el tiempo de ejecución. El problema con esto es que solo funciona para la compilación de todo el programa. Si Google-Go pudiera compilar archivos DLL modulares (que no puede), se encontraría con el problema de que no hay forma de decir que los objetos de la lista deben admitir una interfaz específica de tres métodos, aunque No los llamo hoy porque podría llamarlos en el futuro.
Entre esas dos soluciones, le gusta el intercambio y la verdad.
Personalmente, me gustaría ver que Objective-C agregue la conformidad del protocolo paramétrico, por lo que podría pedir al compilador que asegure que el contenido de una colección en particular siempre se ajuste a un conjunto dado de protocolos.
También me gustaría que el compilador me ayudara a evitar el exceso de conformidad. Si no estoy llamando a métodos en esos protocolos sobre objetos, debería generar errores/advertencias diciéndome eso. Si quiero mantenerlos en el protocolo a pesar de que no los estoy usando, debería hacer una declaración explícita para cada método en el protocolo que "podría usarse en el futuro, por lo que todos los elementos deben suministrarlo ahora". ". Esto al menos hace que el proceso de exceso de conformidad requiera MÁS trabajo, en lugar de Java/C#, donde requiere menos trabajo.
"De hecho, mirar los tipos reales es una muy mala práctica en Obj-C y muy desalentada". ¿Puede explicar más?Todos los objetos de datos estándar se implementan con herencia, no con protocolos. Tome como ejemplo NSDecimalNumber: NSNumber: NSValue: NSObject. O bien, NSString que tampoco proporciona un protocolo. Por lo tanto, de las dos opciones de tiempo de compilación, isKindOfClass: se puede usar mientras que conformsToProtocol: no se puede. ¿Cómo es esa mala práctica? –
- 1. ¿Hay algo así como Lista <String, Int32, Int32> (lista genérica multidimensional)
- 2. ¿Hay algo así como indicadores en Lua?
- 3. ¿Hay algo así como find_if en Java?
- 4. ¿Hay algo así como `last` for` map`?
- 5. ¿Hay algo así como Incanter para Haskell?
- 6. ¿Hay algo así como un modelo funcional?
- 7. ¿Hay algo así como Codecademy para Java
- 8. ¿Hay algo así como WMI para Linux?
- 9. ¿Hay algo así como "global ::" para VB.NET?
- 10. ¿Hay algo así como bpython para Ruby?
- 11. ¿Hay algo así como AutoMapper para Scala?
- 12. ¿Hay algo así como una clase interna en Java?
- 13. ¿Hay algo así como una altura de línea automática?
- 14. ¿Hay algo así como i en rango (longitud) en PHP?
- 15. ¿Hay algo así como memcached, pero para listas ordenadas?
- 16. ¿Hay algo así como Eclipse Perspective en Visual Studio?
- 17. ¿Hay algo así como un carácter comodín en Java?
- 18. ¿Hay algo así como herencia de anotación en java?
- 19. ¿Hay algo así como linux ptrace syscall en Windows?
- 20. ¿Hay algo así como var_dump de PHP en c/C++?
- 21. ¿Hay algo así como un bool nulo en vb.net
- 22. ¿Hay algo así como un flujo nulo en Ruby?
- 23. ¿hay algo así como isset de php en javascript/jQuery?
- 24. ¿Hay algo así como TimeSpan en el desarrollo de Android?
- 25. ¿Hay algo así como Restrictions.eq (verdadero, falso) en Criteria API?
- 26. ¿Hay algo así como MasterPages en CodeIgniter Framework?
- 27. ¿Hay algo así como PHP preg_replace_callback() en javascript?
- 28. ¿Hay algo así como sesión en la aplicación de Windows?
- 29. ¿Hay algo así como printf en Action Script 3?
- 30. ¿Hay algo así como plantillas genéricas en django como vistas genéricas
Objective-C es un sistema basado en la conformidad del protocolo (interfaz), en lugar de las relaciones de tipo. OMI, lo que realmente quieres decir es: ¿hay alguna forma para que el compilador cree instancias de tipos de colecciones de manera que todos los elementos de la colección se ajusten a un protocolo determinado (interfaz)? –