2011-09-02 12 views
8

Tengo una clase A con una propiedad NSString *name. Si tiene un NSArray y agrega muchos objetos A en esta matriz, ¿es necesario el fundido cada vez que recupero un objeto? es decir,NSArray de objetos y Casting

NSString* n = (NSString*)[arr objectAtIndex:1]; 

O hay una otra manera de hacerlo un poco como en Java, donde tienes ArrayList<A> arr?

Respuesta

20

NSArray no almacena información sobre los tipos de objetos que contienen. Si usted sabe con seguridad los tipos de objetos en su conjunto, puede realizar un molde, ya sea implícita o explícitamente:

NSString *n = [arr objectAtIndex:1]; // implicit type conversion (coercion) from id to NSString* 
NSString *n = (NSString *)[arr objectAtIndex:1]; // explicit cast 

No hay diferencia en el costo de tiempo de ejecución entre conversiones implícitas y explícitas, es sólo una cuestión de estilo. Si obtiene el tipo incorrecto, entonces lo más probable es que obtenga la temida excepción unrecognized selector sent to instance 0x12345678.

Si usted tiene un conjunto heterogéneo de diferentes tipos de objetos, es necesario utilizar el método isKindOfClass: para probar la clase del objeto:

id obj = [arr objectAtIndex:1]; 
if ([obj isKindOfClass:[NSString class] ]) 
{ 
    // It's an NSString, do something with it... 
    NSString *str = obj; 
    ... 
} 
+2

Vale la pena señalar que no hay forma de distinguir entre NSStrings y NSMutableStrings en tiempo de ejecución; todos responden SÍ a 'isKindOfClass: [NSMutableString class]'. – Chuck

+0

@Chuck: No lo sabía. ¿Cómo? –

+0

@Chuck: Noté que NSString también devuelve SÍ a '[myNSString respondsToSelector: @" appendFormat:]; '. ISTM que las cadenas mutables e inmutables son implementadas por __NSCFString y que tiene un indicador interno que le dice si es mutable o no Si llama a '[myNSString appendFormat: @" world "];' obtendrá una excepción, pero no una que indique que no responde al selector. Aparentemente 'appendFormat:' verifica la bandera inmutable y, si está configurada, lanza una excepción. Las cadenas mutables e inmutables son, de facto, la misma clase, '__NSCFString'. –

1

Esta es la manera de hacerlo. En realidad, puede hacer la operación anterior sin emitir el retorno, ya que lo está leyendo en un NSString de todos modos.

-2

esta es la forma:

NSMutableArray *objectsArray = [[NSMutableArray alloc] init]; 

A *a= [[A alloc] init]; 

[objectsArray addObject:a]; 

[a release]; 

Usted no tiene que preocuparse por el tipo PROPRETY

+0

que las fugas de código ... – Daniel

+2

realidad no, añadiendo a la array conserva el objeto por lo que después de ese fragmento tiene un número de retención de +2, por lo que realmente tendría que quitar el elemento y liberarlo para que no se filtre, todo esto es una mala práctica, debería haber dicho esto el código puede provocar fugas. – Daniel

+0

Daniel tiene razón al señalar que este es un estilo pobre. Solo hay una referencia a la instancia de 'A', que es a través de la matriz, pero tanto la matriz como el código' alloc'ing tienen derechos de propiedad sobre ella./cc @Chuck –

11

NSArray 's objectAtIndex: devuelve una variable de tipo id. Esto sería más o menos equivalente a devolver un Object en Java: "no podemos garantizar mucho sobre el tipo de esta variable". Sin embargo, en Objective-C, puede enviar mensajes a las variables id sin quejarse el compilador. Entonces, como sabe que la matriz solo contiene A instancias, puede enviar el mensaje name. Por ejemplo, la siguiente compilará sin previo aviso:

NSString *name = [[array objectAtIndex:0] name]; 

Sin embargo, si desea utilizar la notación de puntos (por ejemplo [array objectAtIndex:0].name), tendrá que emitir el id a un A * como se muestra aquí:

NSString *name = ((A *)[array objectAtIndex:0]).name; 
+0

perfecto ... solo la información que estaba buscando – Tim

Cuestiones relacionadas