lunes, 1 de noviembre de 2010

Invocación dinámica de funciones en Objective-C

Tengo el siguiente problema: tengo un objeto que tiene tres propiedades (o métodos, en Objective-C se pueden invocar como métodos), que tienen nombres "sourceUrl1", "sourceUrl2" y "sourceUrl3".

En una determinada función, recibo por parámetro el número de la propiedad que quiero usar.

El código "tradicional" para hacer esto, sería con un switch, discriminando por el valor del parámetro. Algo así:
NSString *strUrl;
switch (indexPath.row) {
  case 0:
    strUrl = question.sourceUrl1;
    break;
  case 1:
    strUrl = question.sourceUrl2;
    break;
  case 2:
    strUrl = question.sourceUrl3;
    break;
}
Pero Objective-C tiene la ventaja de ser dinámico. De esa forma, puedo construir el nombre de la propiedad usando un string, e invocarlo a partir de ese nombre.

El código usando esta propiedad del lenguaje es:
NSString *selectorName = [NSString stringWithFormat:@"sourceUrl%d", indexPath.row+1];
NSString *strUrl = [question performSelector:NSSelectorFromString(selectorName)];
Me gusta cuando encuentro que se pueden resolver las cosas de una forma más simple :)

2 comentarios:

  1. Me encanta la programación dinámica pero es curiosa la definición de "mas simple".

    La primera implementación la entiende cualquier y es facil de mantener. La segunda solución es mas general pero mucho mas difícil de entender y mantener. Ademas sin control de errores abre una puerta en la seguridad enorme.


    Esperemos que algún día se pueda programar usando MacRuby y quedaría algo así

    question.send("sourceUrl#{indexPath.row}")

    ResponderEliminar
  2. Alejandro:

    Más simple es, lo que no es más simple es la sintaxis de Obj-C, pero uno se acostumbra... Es verdad que en Ruby es mucho más fácil de leer (esto, a veces Rails parece Chino).

    En cuanto a la seguridad, en este caso no es problema porque es dentro de un método privado. Además el número no es ingresado por el usuario y es un int (si fuera string es peor).

    ResponderEliminar