2011-07-06 10 views
8

Si quiero devolver una matriz inmutable como esta + (NSArray *)ids pero dentro de este método declaro NSMutableArray porque quiero ordenarlo usando -sortUsingSelector:.Método de retorno Objective-c que devuelve NSMutableArray en lugar del tipo de devolución NSArray declarado

Volviendo a este método funciona perfecto.

  • ¿Pero está "bien" escribir código que declara que el método de retorno debe ser de un tipo y el tipo de realidad es otro?

  • Esto funciona porque NSMutableArray es una subclase de NSArray?

  • ¿El valor de retorno real es NSArray o NSMutableArray?

+3

En cualquier idioma, el tipo de retorno real de una función puede ser un subtipo del tipo de retorno declarado como consecuencia del [principio de sustitución de Liskov] (http://en.wikipedia.org/wiki/Liskov_substitution_principle). – outis

Respuesta

6

(...) es que "bien" para escribir código que declare que el método de retorno debe ser un tipo y el tipo actualy es otro?

Sí, se proporciona los tipos son compatibles; ver el siguiente párrafo. De hecho, hay algunos casos en Cocoa (en particular, grupos de clases) que hacen eso también.

Esto funciona porque NSMutableArray es una subclase de NSArray?

Exactamente. Como NSMutableArray es una subclase de NSArray, hereda todos sus métodos y propiedades declaradas, por lo que se comporta públicamente como NSArray. Esto se llama Liskov substitution principle.

¿El valor de retorno real es un NSArray o un NSMutableArray?

El valor de retorno es lo que devuelve. Como devuelve un NSMutableArray, es un NSMutableArray. Desde la perspectiva de la persona que llama, es un objeto que se puede usar como un NSArray.

+5

Devolver una matriz mutable de un método escrito como devolver un 'NSArray *' está bien, pero mutar la matriz que obtiene de un método escrito como devolver un 'NSArray *' no es correcto. Si la declaración del método no dice explícitamente que devuelve una matriz mutable, usted, la persona que llama, nunca debe suponer que devuelve una matriz mutable. Incluso hacerlo dentro de tu propia aplicación significa que estás creando tu propio código mucho más frágil. Si la clase dice a su propia matriz que se ordene a sí misma, el método debe ser un descriptor de acceso explícitamente retornable. Cualquier otra clase debe hacer su propia copia mutable. –

+0

@ Peter Oseas: +1. Los documentos de Apple prohíben explícitamente tratar un objeto como mutable si la API lo anuncia como inmutable * incluso si lo prueba primero y descubre que es mutable *. – JeremyP

+1

@Jer Y [la prueba de mutabilidad no es tan simple como podría parecer inicialmente] (http://stackoverflow.com/q/1788690/557219). –

2
  • Si está "bien" o no, es una pregunta difícil. Si es un proyecto pequeño y solo usted usa el código, podría ser correcto. Sin embargo, si no confía en que nada pueda cambiar el "NSArray" devuelto, no está bien. (Consulte el último punto)

  • Sí.

  • Es un NSMutableArray. Un elenco simple le permitirá cambiar los valores en él.

Si realmente quiere un retorno de un objeto inmutable, haga lo siguiente:

NSArray* immutableArray = [[mutableArray copy] autorelease]; 
    return immutableArray; 
+0

No olvide liberarlo automáticamente, cuando no se ejecuta bajo GC o ARC. –

+0

Es cierto, editado para reflejar eso. – uvesten

Cuestiones relacionadas