Cosas que me gustaría tener en Objective-C
En los últimos tiempos, el lenguaje Objective-C ha mejorado bastante, como ya hemos comentado en el blog (por ejemplo acá).
Pero (siempre hay un "pero"), igual hay algunas cosas que todavía se podrían mejorar o agregar al lenguaje.
Cuando uso una variable que está basada en este protocolo (id<MyProtocol> myVar), puedo ver cuantos elementos tiene el array escribiendo
Una alternativa sería tener algo así como "method templates", donde se pudiera definir la implementación del método en el protocolo mismo. Estos templates solo podrían usar otros métodos y propiedades definidos en el protocolo.
El ejemplo más claro de esto es con los "singleton". Una posible implementación es la siguiente:
Nótese que en esta implementación no se hace nunca referencia a la clase donde está definido el método. Lo único que se requiere es que tenga un método init.
Si tuviera algo equivalente a los módulos de Ruby (cuando se usan como "mixins"), podría simplemente "declarar" que una clase es un singleton, y que eso incluya la implementación del método sharedInstance.
Esto es muy útil, y por ejemplo los arrays no controlan el tipo de objeto, por lo que podemos tener por ejemplo un número y un texto en el mismo array.
Sin embargo, hay veces que es útil saber de que tipo son los elementos de una colección, y forzar a que no se agreguen elementos de otro tipo.
Supongamos el caso que tenemos un protocolo que define una propiedad
Pero (siempre hay un "pero"), igual hay algunas cosas que todavía se podrían mejorar o agregar al lenguaje.
Implementación default para métodos de protocolos
Supongamos que tenemos un @protocol MyProtocol, que define una @property NSArray *someArray.Cuando uso una variable que está basada en este protocolo (id<MyProtocol> myVar), puedo ver cuantos elementos tiene el array escribiendo
[[myVar someArray] count]Pero supongamos que esto lo hago muy seguido, entonces quiero cambiar esto, para que el protocolo ya defina la propiedad elementCount para poder usarla como
[myVar elementCount]¿Cuál es el problema con esto? Que si agrego la propiedad elementCount al protocolo, tengo que implementarla en todas las clases que implementan el protocolo.
Una alternativa sería tener algo así como "method templates", donde se pudiera definir la implementación del método en el protocolo mismo. Estos templates solo podrían usar otros métodos y propiedades definidos en el protocolo.
Templates o módulos
Yendo en la misma línea, hay casos en que una implementación de un método es genérica, sin importar la clase en la que esté.El ejemplo más claro de esto es con los "singleton". Una posible implementación es la siguiente:
+ (instancetype)sharedInstance {(tomada de NSHipster, un excelente blog sobre Objective-C, ya que estamos)
static id _sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}
Nótese que en esta implementación no se hace nunca referencia a la clase donde está definido el método. Lo único que se requiere es que tenga un método init.
Si tuviera algo equivalente a los módulos de Ruby (cuando se usan como "mixins"), podría simplemente "declarar" que una clase es un singleton, y que eso incluya la implementación del método sharedInstance.
Generics
En las APIs de Objective-C, cuando un método espera recibir un objeto genérico, declara que recibe un id, que indica que puede recibir cualquier tipo de objeto.Esto es muy útil, y por ejemplo los arrays no controlan el tipo de objeto, por lo que podemos tener por ejemplo un número y un texto en el mismo array.
Sin embargo, hay veces que es útil saber de que tipo son los elementos de una colección, y forzar a que no se agreguen elementos de otro tipo.
Supongamos el caso que tenemos un protocolo que define una propiedad
@property (nonatomic, strong) NSArray *actions;¿De qué tipo pueden ser las actions? No lo sabemos, a no ser que quien escribió el protocolo haya puesto un comentario... El lenguaje me debería ayudar a que esto quede más claro.
Boxing (y unboxing) de tipos básicos
En Objective-C, los arrays y los diccionarios solo pueden contener objetos, por lo que si queremos guardar por ejemplo un int en un array, tenemos que hacer el "boxing"y pasarlo al array como un NSNumber *.
Si bien no es algo complicado de hacer, por ejemplo;
int someInteger = 1;podría ser el compilador el que se encargue de hacerlo...
NSArray *myArray = [NSArray arrayWithObject: @(someInteger) ];
Map & Reduce
Las funciones que tiene la API para manipular colecciones, en ciertos aspectos son bastante limitados.
Por ejemplo, no tengo funciones para Map y Reduce, que son muy útiles. Son fáciles de implementar, pero ya podrían venir incluidas.
Otras, por ejemplo para filtrar un array, son demasiado complicadas:
Por ejemplo, no tengo funciones para Map y Reduce, que son muy útiles. Son fáciles de implementar, pero ya podrían venir incluidas.
Otras, por ejemplo para filtrar un array, son demasiado complicadas:
[[someArray filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^(id evaluatedObject, NSDictionary *bindings) {Debería poder escribir simplemente
/* filtering code goes here */
}];
[someArray filterWithBlock:^(id evaluatedObject) {
/* filtering code goes here */
}];
Comentarios
Publicar un comentario