2010-07-10 13 views
66

He intentado inicializar mi NSMutableArray 100 formas desde el domingo, y NADA está funcionando para mí. Intenté configurarlo igual a un NSMutableArray recién asignado e inicializado, solo asignando, inicializando la variable por sí mismo, cada combinación que podía pensar y siempre el mismo resultado.NSMutableArray addObject: - [__ NSArrayI addObject:]: selector no reconocido enviado a la instancia

Aquí está el código:

Object.h

NSMutableArray *array; 

@property (copy) NSMutableArray *array; 

Object.m

@synthesize array; 

if (self.array) { 
    [self.array addObject:anObject]; 
} 
else { 
    self.array = [NSMutableArray arrayWithObjects:anObject, nil]; 
} 

NOTA: En depuración "unObjeto" no es nula en el momento de la ejecución ...

He probado un Objeto y es La inicialización funciona bien, pero sigo recibiendo el siguiente error cuando Intento agregarObject: a self.array.

2010-07-10 11: 52: 55.499 MyApp [4347: 1807] - [__ NSArrayI addObject:]: selector no reconocido enviado a instancia 0x184480

2010-07-10 11: 52: 55.508 MyApp [4347: 1807] *** terminación de aplicación debido a excepción no detectada 'NSInvalidArgumentException', razón: '- [__ NSArrayI addObject:]: selector no reconocido enviado a la instancia 0x184480'

¿alguien tiene alguna idea de lo que va mal ?

Respuesta

11

Me gustaría inclinar mi sombrero a Georg Fritzsche.Terminé necesitando usar (copiar) en lugar de (retener), y no habría sabido qué hacer sin su aporte.

//@property (copy) NSMutableArray *array; 
@property (nonatomic, copy) NSMutableArray *array; //overridden method is non-atomic as it is coded and should be reflected here. 

Si desea utilizar (copia) en un objeto mutable debe invalidar el método "setter" de la siguiente manera ...

- (void)setArray:(NSArray *)newArray { 

    if (array != newArray) { 
     [array release]; 
     array = [newArray mutableCopy]; 
//  [array retain]; // unnecessary as noted by Georg Fritzsche 
    } 

    return; 
} 

NOTA: Usted recibirá una advertencia del compilador: Objetivo Incompatible -C-types inicializando 'struct NSArray *', esperado 'struct NSMutableArray *' Decidí declarar el parámetro newArray como un (NSArray *), porque se te da la flexibilidad de tener cualquier matriz pasada y copiada correctamente a tu (NSMutableArray *) variable. Si desea declarar el nuevo parámetro Array como (NSMutableArray *), deberá dejar el método mutableCopy en su lugar para obtener los resultados deseados.

¡Salud a Georg! Z @ K!

+0

Tenga en cuenta que su declaración de propiedad no tiene que coincidir con el tipo ivar, por lo que debe utilizar' @property (nonatomic, copy) NSArray * array; 'en tu caso. También tenga en cuenta que su propiedad es implícitamente atómica, pero la implementación de su setter no es - vea [Atomicity] (http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html # // apple_ref/doc/uid/TP30001163-CH17-SW28). –

+1

Finalmente, '-mutableCopy' ya devuelve una instancia retenida, por lo que no es necesario' [retención de matriz] '- ver [Política de propiedad de objeto] (http://developer.apple.com/mac/library/documentation/Cocoa /Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html#//apple_ref/doc/uid/20000043-SW1). –

+0

Gracias de nuevo, Sr. Fritzsche. Tenía curiosidad acerca de ese retener extra, pero parecía funcionar en mi programa. Aparentemente tengo un error en otro lado. : -/Usted es el hombre, gracias por contribuir en esta publicación y, inadvertidamente, en mi programa; ¡Aprecio tu tiempo! Atentamente, Z @ K! – Zak

81

El setter sintetizado para @property (copy) envía un mensaje copy a la matriz, lo que da como resultado una copia inmutable.

No tiene más remedio que implementar el ajustador usted mismo aquí, como detailed en la guía de Objective-C.

+0

ABSOLUTAMENTE CORRECTO!Me di cuenta cuando estaba escribiendo mi publicación, y publiqué mi resolución a continuación. Realmente no consideré anular al setter, pero en mi caso realmente no necesito una copia, así que mi solución funcionó para mí. ¡Gracias por la rápida respuesta! - Z @ K! – Zak

+1

El enlace a la guía Objective-C está roto. – johnnieb

69

Como estaba probando la lectura de mi publicación, se me ocurrió una idea y respondí mi propia pregunta. Esta resolución fue lo suficientemente oscura como para que decidiera seguir adelante, crear la publicación y responderla yo mismo (para que ningún otro novato, como yo, se quede colgado).

Mi error fue ...

@property (copy) NSMutableArray *array; 

que debería haber sido ...

@property (retain) NSMutableArray *array; 

El error no estaba sucediendo en la forma en que se estaba ejecutando el código, sino más bien en el forma en que anObject estaba intentando "copiar" la matriz NSMutableArray.

Como todos sabemos ...

mutableArray = [mutableArray copy]; 

no es siempre (o nunca, en mi experiencia) igual a ...

mutableArray = [mutableArray mutableCopy]; 

y esta fue la fuente de mi problema. Simplemente al cambiar @property de (copiar) a (retener) resolví mi problema.

+0

estaba teniendo el mismo problema, he resuelto mi cambio de propiedad de la copia para retener ... @ Zak +1 para su respuesta. – Rupesh

+0

Debe marcar esto como la respuesta aceptada. – NathanAldenSr

+1

'mutableCopy' acaba de guardar mi vida – michaelsnowden

-4

Esta excepción puede ocurrir si uno de los objetos en la matriz es nulo.

+1

No es este error en particular, no. Obtendrá una excepción diferente si intenta insertar un objeto nil. –

+0

Más allá de eso, las matrices pueden contener NSNull simplemente bien. – stephencelis

3

Me estaba dando el mismo error, a pesar de que mis propiedades eran fuertes (utilizando ARC) y asigné la matriz con NSMutableArray.

Lo que sucedía era que estaba archivando la matriz mutable (ya que contiene objetos personalizados) para su uso futuro y al decodificarla, devuelve una copia inmutable.

Espero que ayude a cualquiera por ahí.

3

Tiene algunos índices (en una matriz de datos en otro lugar) y desea tenerlos en orden numérico (por una buena razón). Se bloquea hasta que se agrega mutableCopy al final. Totalmente desconcertado, hasta que recordé que usando Objective-C literal @ [] devuelve una matriz no mutable.

NSMutableArray *a = [@[@(self.indexA), @(self.indexB)] mutableCopy]; 
NSLog(@"%@", a); 
[indexArray sortUsingComparator: ^(NSNumber *obj1, NSNumber *obj2) { 
    return [obj1 compare:obj2]; 
}]; 
NSLog(@"%@", a); 

Thanx, Zak!

0

Me picaron por esta excepción por un error tipográfico que hice, tal vez le ahorrará a alguien 5 min. de su tiempo:

escribí:

NSMutableArray *names = [NSArray array]; 

en lugar de:

NSMutableArray *names = [NSMutableArray array]; 

El compilador no tiene problemas con eso porque NSMutableArray es también un NSArray, pero se bloquea cuando se trata de añadir una objeto.

0

El error se produjo como resultado de intentar agregar un objeto a un tipo NSMutableArray que apuntaba realmente a un objeto NSArray. Este tipo de escenario se muestra en algún código de demostración a continuación:

NSString *test = @"test"; 
NSMutableArray *mutableArray = [[NSMutableArray alloc] init]; 
[mutableArray addObject:test]; 
NSArray *immutableArray = [[NSArray alloc] init]; 
mutableArray = immutableArray; 
[mutableArray addObject:test]; // Exception: unrecognized selector 

en el código anterior, es fácil ver que un tipo subclase está siendo asignado a un tipo superclase. En Java, por ejemplo, esto se habría marcado inmediatamente como un error (error de conversión entre tipos) y el problema se resolvió con bastante rapidez. Para ser justos con Objective-C, se da una advertencia cuando se intenta realizar una tarea incompatible, sin embargo, esto simplemente no parece ser suficiente a veces y el resultado puede ser un verdadero dolor para los desarrolladores. Afortunadamente, esta vez, no fui yo quien soportó la mayor parte de este dolor: P

Cuestiones relacionadas