Sobrecarga de método em Objective-C?

131

Tanto quanto sei, o Objective-C não suporta sobrecarga de método. Qual pode ser a alternativa para isso no Objective-C? Ou devo sempre usar um nome de método diferente?

suse
fonte

Respostas:

193

Correto, o objetivo-C não suporta sobrecarga de método, portanto, você deve usar nomes de métodos diferentes.

Observe, no entanto, que o "nome do método" inclui as palavras-chave de assinatura do método (os nomes dos parâmetros anteriores a ":" s); portanto, dois métodos diferentes são os seguintes , mesmo que ambos comecem a "writeToFile":

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

(os nomes dos dois métodos são "writeToFile: fromInt:" e "writeToFile: fromString:").

David Gelhar
fonte
4
@RaheelSadiq Não está sobrecarregando porque os nomes dos métodos (no ObjC: 'seletores') são diferentes. Sendo diferente, nenhum deles é considerado "sobrecarregado". Se writeToFile: from: fosse definido duas vezes, com apenas os tipos de parâmetro diferentes, isso seria sobrecarregado. Conforme afirmado, porém, isso não é suportado no ObjC, como ocorre com outras linguagens, incluindo Java e agora Swift.
9189 Chris Hatton #
Não apenas os nomes dos parâmetros, mas até os dois pontos fazem parte do nome do método, de modo que - (void) writeToFile: (NSString *) caminho: (int) anInt; e - (void) writeToFile: (NSString ) path: (NSString ) aString; também são métodos diferentes.
Kaiserludi
22

Vale ressaltar que, mesmo que o Objective-C não suporte sobrecarga de método , o Clang + LLVM suporta sobrecarga de função para C. Embora não seja exatamente o que você está procurando, pode ser útil em algumas situações (por exemplo, quando implementação de uma versão ligeiramente hackeada (contrária ao encapsulamento) do padrão de design do visitante )

Aqui está um exemplo simples de como funciona a sobrecarga de funções:

__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
fonte
Alguém poderia pensar que essa dica, combinada com o método swizzling, poderia realmente levar a métodos "sobrecarregáveis" ... Por que alguém precisaria, com ide isKindOfClass:à disposição, porém, é uma história diferente ...
Alex Gray
1
@alexgray Entendo seu ponto de vista ide abordo isKindOfClass:os cenários mais práticos. Um dos motivos pelos quais você pode preferir sobrecarregar é a seleção automática do tipo mais específico atendido, o que acarretaria uma pequena sobrecarga a ser mantida com a verificação explícita de tipos.
9189 Chris Hatton #
1
A documentação do Clang diz explicitamente que o que ele faz é fornecer o nome do C ++ para C. e isso é basicamente o compilador automaticamente fazendo nos bastidores o que se faz no Objective-C, fornecendo nomes de métodos que são distintos ao incluir (em formato mais longo) os tipos de argumento.
Chris Stratton
19

David está correto, pois o método de sobrecarga não é suportado no Objective-C. É semelhante ao PHP nesse sentido. Como ele também aponta, é prática comum definir dois ou mais métodos com assinaturas diferentes, da maneira que ele exemplifica. No entanto, também é possível criar um método usando o tipo "id". Através do tipo "id", você pode enviar qualquer objeto (e quaisquer primitivas usando a classe NSNumber) para o método e, a partir do próprio método, pode testar seu tipo e lançar a exceção apropriada, se necessário. Embora isso tenha um impacto menor no desempenho, provavelmente será nominal ou insignificante, a menos que você esteja processando grandes quantidades de dados.

- (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 também é um belo local para implementar um protocolo para aplicar o tipo de objeto, o que pode ser feito da seguinte maneira:

(id<MyProtocol>)object
Ziminji
fonte