2010-12-04 14 views
5

Estoy tratando de subclase NSArray, pero se bloquea la aplicación al intentar acceder al método de recuento. Sé que NSArray es un clúster de clase .Objetivo C - Subclase de NSArray

  • Pero, ¿qué significa esto?
  • ¿Existe una solución alternativa para poder crear una subclase de un NSArray?

sé que sólo puedo subclase NSObject y tener mi matriz como una variable de instancia pero preferiría subclase NSArray.

EDIT: Motivo: estoy creando un juego de cartas, tengo una clase Deck que debe subclase NSMutableArray tener un par de métodos adicionales (-shuffle, -removeObjects:, -renew, etc.), y creo que lo hará mira más limpio a la subclase NSArray en lugar de tener una var.

+0

¿por qué es necesario crear una subclase? – MCannon

+3

Podría simplemente crear una categoría para agregar los métodos adicionales en lugar de subclases :( – aryaxt

+2

+1 para categorías. Subclases NS * Matriz para esto es una exageración seria que las categorías de Objective-C hacen completamente innecesario. –

Respuesta

16

El problema con la adición de una categoría en una clase como esta es que todas las instancias de la clase heredarán los métodos adicionales. Eso es innecesario (ya que no todas las matrices necesitan ser mezcladas, etc.) y peligroso (porque no puede beneficiarse de la comprobación de tipografía para asegurarse de que la NSArray a la que se está refiriendo actualmente es realmente una que se espera que se mezcle)

Una alternativa sería crear su propia clase Deck que tenga un NSMutableArray como variable de instancia. Allí puede definir acciones en su mazo exactamente como lo desea, y el hecho de que esté utilizando un NSMutableArray se convierte en un detalle de implementación. Esto le permite aprovechar la comprobación de tipos en tiempo de compilación y le permite cambiar la implementación interna de su clase de Deck sin cambiar sus clientes. Por ejemplo, si decidió por algún motivo que un NSMutableDictionary sería una mejor copia de seguridad, puede hacer todos esos cambios dentro de la implementación de su clase Deck sin cambiar el código que crea y utiliza el Deck.

+2

@ Ryan - No hay gastos generales por instancia para agregar una categoría ... – nielsbot

+1

No creo que esté implicando que hay una sobrecarga técnica , él solo dice que cada instancia gana la funcionalidad de su "subclase", wh éter es relevante o no. Por ejemplo, llamar accidentalmente "-shuffle" en un NSArray de objetos no intencionados puede o no funcionar y no debe permitirse. –

6

lo general, no necesita una subclase, pero en cualquier caso las sugerencias realizadas por Apple son:

Cualquier subclase de NSArray debe invalidar los métodos de instancia primitivos count y objectAtIndex:. Estos métodos deben operar en la tienda de respaldo que proporcione para los elementos de la colección. Para esta tienda de respaldo puede usar una matriz estática, un objeto NSArray estándar o algún otro tipo de datos o mecanismo. También puede elegir anular, parcial o totalmente, cualquier otro método NSArray para el que desee proporcionar una implementación alternativa.

¿De verdad reemplazó el método count? Como dicen, debe proporcionar su propia estructura de respaldo para contener los elementos de la matriz y anular los métodos sugeridos teniendo en cuenta esto ...

+0

mm intenté sobreescribir cuentas y llamar [supercuento] pero eso no funcionó – aryaxt

+1

debe proporcionar su propia matriz de respaldo, sin depender de la ya proporcionada por NSArray; de lo contrario, podría simplemente usar una NSArray como variable de instancia y asignar el 'conteo' original al interior NSArray count – Jack

3

Si solo está agregando métodos nuevos y está utilizando la tienda de respaldo existente, entonces un mejor enfoque es agregue una categoría a NSArray. Las categorías son una parte realmente poderosa del objetivo-C, ver cocoadev para algunas muestras.

+2

Agregar una categoría a NSArray para agregar funcionalidad específica de la aplicación generalmente es una mala idea – bbum

-1

En este caso particular, mezclaré la matriz usando - sortedArrayUsingComparator: y haré que su comparador muestre aleatoriamente NSOrderedAscending o NSOrderedDescending.

por ejemplo:

NSArray *originalArray; // wherever you might get this. 
NSArray *shuffledArray = [orginalArray sortedArrayUsingComparator: 
    ^(id obj1, id obj2) { 
    return random() % 2 ? NSOrderedAscending : NSOrderedDescending; 
    }]; 
+0

Bastante seguro de que no funcionará, ya que nunca se resolverá en un estado estable. – bbum

+0

En realidad, funciona. Mezclar una matriz que contiene @ "A" .. @ "J" termina llamando al bloque de comparación 19 veces. – NSResponder

+0

incorrecto Los algoritmos de ordenación necesitan un orden total, que es exactamente uno de a> b, a

0

NSMutableArray ya tiene un - (void)removeObjectsInArray:(NSArray *)otherArray; Usted va a estar mejor fuera de hacer una subclase NSObject con una propiedad de matriz mutable.

Cuestiones relacionadas