Método de sobrecarga en Objective-C?

131

Hasta donde yo sé, Objective-C no admite la sobrecarga de métodos. ¿Cuál puede ser la alternativa para esto en Objective-C? ¿O debería usar siempre un nombre de método diferente?

suse
fuente

Respuestas:

193

Correcto, el objetivo-C no admite la sobrecarga de métodos, por lo que debe usar diferentes nombres de métodos.

Sin embargo, tenga en cuenta que el "nombre del método" incluye las palabras clave de firma del método (los nombres de los parámetros que aparecen antes de ":" s), por lo que los siguientes son dos métodos diferentes , a pesar de que ambos comienzan a "writeToFile":

-(void) writeToFile:(NSString *)path fromInt:(int)anInt;
-(void) writeToFile:(NSString *)path fromString:(NSString *)aString;

(los nombres de los dos métodos son "writeToFile: fromInt:" y "writeToFile: fromString:").

David Gelhar
fuente
44
@RaheelSadiq No se está sobrecargando porque los nombres de los métodos (en ObjC: 'selectores') son diferentes. Siendo diferente, ninguno de los dos se considera 'sobrecargado'. Si writeToFile: from: se definiera dos veces, con solo los tipos de parámetros diferentes, eso sería una sobrecarga. Sin embargo, como se indicó, esto no es compatible con ObjC, como ocurre con otros lenguajes, incluidos Java y ahora Swift.
Chris Hatton el
No solo los nombres de los parámetros en sí, sino que incluso los dos puntos son parte del nombre del método, de modo que - (vacío) writeToFile: (NSString *) ruta: (int) anInt; y - (vacío) writeToFile: (NSString ) ruta: (NSString ) aString ; también son métodos diferentes.
Kaiserludi
22

Vale la pena mencionar que incluso si Objective-C no admite la sobrecarga de métodos , Clang + LLVM sí admite la sobrecarga de funciones para C. Aunque no es exactamente lo que está buscando, podría resultar útil en algunas situaciones (por ejemplo, cuando implementar una versión ligeramente pirateada (va en contra de la encapsulación) del patrón de diseño del visitante )

Aquí hay un ejemplo simple de cómo funciona la sobrecarga de funciones:

__attribute__((overloadable)) float area(Circle * this)
{
    return M_PI*this.radius*this.radius;
}

__attribute__((overloadable)) float area(Rectangle * this)
{
    return this.w*this.h;
}

//...
//In your Obj-C methods you can call:
NSLog(@"%f %f", area(rect), area(circle));
Valentin Radu
fuente
Uno podría pensar que esta sugerencia, combinada con la combinación de métodos, podría conducir a métodos "sobrecargables" ... Por qué uno tendría que, con idy isKindOfClass:a su disposición, sin embargo, es una historia diferente ...
Alex Gray
1
@alexgray Entiendo tu punto idy isKindOfClass:cubro los escenarios más prácticos. Una razón por la que podría preferir la sobrecarga es la selección automática del tipo más específico atendido, que incurriría en una pequeña sobrecarga para mantener con una verificación de tipo explícita.
Chris Hatton
1
La documentación de Clang dice explícitamente que lo que hace es proporcionar el cambio de nombre de C ++ para C. Y eso es básicamente solo el compilador que hace automáticamente detrás de escena lo que uno hace en Objective-C al dar nombres de métodos que son distintos al abarcar (en forma más larga) los tipos de argumentos
Chris Stratton
19

David tiene razón en que el método de sobrecarga no es compatible con Objective-C. Es similar a PHP en ese sentido. Como él también señala, es una práctica común definir dos o más métodos con diferentes firmas en la forma en que ejemplifica. Sin embargo, también es posible crear un método usando el tipo "id". A través del tipo "id", puede enviar cualquier objeto (y cualquier primitiva que use la clase NSNumber) al método y luego desde el propio método puede probar su tipo y lanzar la excepción apropiada si es necesario. Aunque esto tiene un impacto menor en el rendimiento, lo más probable es que sea nominal o insignificante a menos que esté procesando grandes cantidades de datos.

- (void) writeToFile: (NSString *)path fromObject: (id)object {
    if (!([object isKindOfClass: [NSNumber class]] || [object isKindOfClass: [NSString class]])) {
         @throw [NSException exceptionWithName: @"InvalidArgumentException" reason: @"Unrecognized parameter type." userInfo: nil];
    }
}

Este también es un lugar hermoso para implementar un protocolo para imponer el tipo de objeto, que se puede hacer así:

(id<MyProtocol>)object
Ziminji
fuente