objective-c ios nsmutablearray nsarray

objective c - Objetivo C: cómo verificar si la variable es NSArray o NSMutableArray



objective-c ios (7)

¿Cómo puedo verificar si una variable es una NSArray o una NSMutableArray?


Si quieres una matriz mutable, hazlo tú mismo:

NSArray *someArray = /* obtain from somewhere, could be mutable, could be immutable */ NSMutableArray *mutableVersion = [someArray mutableCopy]; // definitely mutable // later [mutableVersion release];

Hay muy pocos casos en los que verificar el tipo interno es una buena idea (otras respuestas ya lo han cubierto). Si desea una matriz mutable, no verifique si una matriz existente es mutable, solo cree la suya para que sepa que es mutable.


Tienes que usar:

[yourArray isKindOf: [NSArray class]]

ya que una simple comparación de las clases puede fallar porque su matriz probablemente no sea una NSArray sino de algún otro tipo de nivel bajo. También puede verificar si su matriz responde a los métodos que necesita.

[yourArray respondsToSelector: @selector(addObject:)]


Utilizar ...

[Array isKindOfClass: [clase NSMutableArray]]

[Array isKindOfClass: [clase NSArray]]

Esto funcionará bien.


Ver el método de -class de NSObject :

NSLog(@"myUnknownArray is of type: %@", [myUnknownArray class]);

También puedes consultar más directamente con el método de la +class :

BOOL isMutableArray = [myUnknownArray isKindOfClass:[NSMutableArray class]];


Yo haría lo siguiente

if([unkownArray isKindOfClass:[NSMutableArray class]]){ // This is a nsmutable array } else if ([unkownArray isKindOfClass:[NSArray class]]){ // This is a nsarray }


* Tenga en cuenta que la implementación de NS {, Mutable} Array ha cambiado desde que se escribió esta respuesta. Como resultado, isKindOfClass: ahora funciona. En qué plataformas dónde y cuándo, no sé.

Hasta que se documente como seguro hacerlo, recomendaría encarecidamente NO escribir código que intente detectar si una colección es mutable o inmutable. Incluso si fuera seguro, tal patrón de diseño es casi siempre indicativo de un defecto de diseño serio.

(Para los que tienen acceso). Rarred archivado: // 10355515 solicitando una aclaración.

Considerar:

int main (int argc, const char * argv[]) { NSArray *array = [NSArray arrayWithObjects: [NSObject new], nil]; NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects: [NSObject new], nil]; NSLog(@"array''s class: %@", NSStringFromClass([array class])); NSLog(@"mutableArray''s class: %@", NSStringFromClass([mutableArray class])); NSLog(@"array responds to addObject: %@", [array respondsToSelector: @selector(addObject:)] ? @"YES" : @"NO"); return 0; }

(Estoy usando matrices no vacías porque una NSArray vacía es lo suficientemente común como para que Cocoa ofrezca una única instancia compartida como una optimización).

array''s class: NSCFArray mutableArray''s class: NSCFArray array responds to addObject: YES

Es decir, ni -isKindOfClass: ni la comprobación de la implementación de addObject: funcionará.

En resumen, no puede distinguir la diferencia entre un NSArray y un NSMutableArray. Esto es por diseño y en gran medida el comportamiento previsto. También es válido para NSString , NSDictionary y NSSet (todos los cuales tienen una subclase mutable ).

Eso puede ser una sorpresa. La realidad, sin embargo, es que los patrones de diseño que requieren la verificación de mutabilidad son confusos de usar e incurren en gastos generales significativos.

Por ejemplo, si la prueba de mutabilidad fuera un patrón común, todos los métodos en Cocoa que devuelven instancias de NSArray tendrían que devolver realmente instancias de NSArray y nunca devolver una referencia al NSMutableArray interno que podría usarse.


Malos pero técnicamente precisos consejos ...

La única manera de hacerlo es invocar [unknownArray addObject:someObject] dentro de un bloque @try / @catch y capturar la NSInternalInconsistencyException que se unknownArray si unknownArray es inmutable (la excepción real podría ser un método no implementado o una clase es inmutable excepción).

Buen consejo...

Sin embargo, la respuesta corta nunca es mirar dentro de un objeto inmutable para ver si es internamente mutable.

La razón por la que se observa la mutabilidad de los objetos inmutables es evitar los métodos en clases que funcionan así:

- (NSArray *)internalObjects { return myInternalObjects; }

el objeto myInternalObjects podría ser mutable pero este método en esta clase está diciendo: no mates lo que te devuelvo. Puede haber serios peligros al hacerlo. Si la clase le permite cambiar la matriz, tendrá un método de acceso o mutador diferente.

Si tiene una clase de amigo que necesita acceso mutable a la variable myInternalObjects, declare una categoría de adaptador especial que solo la clase de amigo importa con un método como

- (NSMutableArray *)mutableInternalObjectsArray;

Esto permitirá que el amigo (que usted asume que es lo suficientemente inteligente como para no violar reglas especiales) tenga el acceso que necesita pero sin exponer la mutabilidad en un sentido más amplio.