O ile mi wiadomo, Objective-C nie obsługuje przeciążania metod. Jaka może być alternatywa dla tego w Objective-C? Czy powinienem zawsze używać innej nazwy metody?
Odpowiedzi:
Prawidłowo, cel-C nie obsługuje przeciążania metod, więc musisz używać różnych nazw metod.
Należy jednak pamiętać, że „nazwa metody” zawiera słowa kluczowe sygnatur metody (nazwy parametrów występujące przed „:” s), więc poniższe są dwiema różnymi metodami, mimo że obie zaczynają się od „writeToFile”:
-(void) writeToFile:(NSString *)path fromInt:(int)anInt;
-(void) writeToFile:(NSString *)path fromString:(NSString *)aString;
(nazwy tych dwóch metod to „writeToFile: fromInt:” i „writeToFile: fromString:”).
Warto wspomnieć, że nawet jeśli Objective-C nie obsługuje przeciążania metod , Clang + LLVM obsługuje przeciążanie funkcji dla C. Chociaż nie jest to dokładnie to, czego szukasz, może się okazać przydatne w niektórych sytuacjach (na przykład, gdy wykonawczych lekko posiekany (sprzeczne hermetyzacji) wersję tego wzorca projektowego gość )
Oto prosty przykład, jak działa przeciążanie funkcji:
__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));
id
i isKindOfClass:
do dyspozycji, to inna historia ...
id
i omawiam isKindOfClass:
większość praktycznych scenariuszy. Jednym z powodów, dla których możesz preferować przeładowanie, jest automatyczny wybór najbardziej konkretnego typu, który jest obsługiwany, co wiązałoby się z niewielkim narzutem przy jawnym sprawdzaniu typu.
David ma rację, ponieważ przeciążanie metody nie jest obsługiwane w Objective-C. W tym sensie jest podobny do PHP. Jak również podkreśla, powszechną praktyką jest definiowanie dwóch lub więcej metod z różnymi podpisami w sposób, w jaki podaje przykłady. Możliwe jest jednak również utworzenie jednej metody przy użyciu typu „id”. Poprzez typ „id” możesz wysłać dowolny obiekt (i wszelkie prymitywy używające klasy NSNumber) do metody, a następnie z poziomu samej metody możesz przetestować jej typ i zgłosić odpowiedni wyjątek, jeśli to konieczne. Chociaż powoduje to niewielki spadek wydajności, najprawdopodobniej będzie to nominalne lub nieistotne, chyba że przetwarzasz duże ilości danych.
- (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];
}
}
Jest to również piękne miejsce na zaimplementowanie protokołu wymuszającego typ obiektu, co można zrobić w następujący sposób:
(id<MyProtocol>)object