Objective-C中的方法重载?


131

据我所知,Objective-C不支持方法重载。在Objective-C中可以替代此方法吗?还是应该始终使用其他方法名称?

Answers:


193

正确,objective-C不支持方法重载,因此您必须使用不同的方法名称。

但是请注意,“方法名称”包括方法签名关键字(“:”之前的参数名称),因此以下是两种不同的方法,即使它们都以“ writeToFile”开头:

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

(这两个方法的名称分别是“ writeToFile:fromInt:”和“ writeToFile:fromString:”)。


4
@RaheelSadiq不会重载,因为方法名称(在ObjC中为“选择器”)是不同的。与众不同,没有人被认为是“超负荷”的。如果对writeToFile:from:进行了两次定义,仅参数类型不同,则将导致重载。如前所述,ObjC不支持此功能,就像其他语言(包括Java和现在的Swift)一样。
克里斯·哈顿

不仅参数名称本身,而且连冒号都是方法名称的一部分,因此-(void)writeToFile:(NSString *)path:(int)anInt; 和-(void)writeToFile:(NSString )path:(NSString)aString;也是不同的方法。
Kaiserludi 2015年

22

值得一提的是,即使Objective-C不支持方法重载,但Clang + LLVM确实支持C的函数重载。尽管并不是您想要的功能,但它在某些情况下可能很有用(例如,当实施轻微砍死(违背封装)版本的的访问者设计模式

这是一个有关函数重载如何工作的简单示例:

__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));

人们会认为这暗示,与方法相结合交叉混合,的确可以导致“重载”的方法...为什么一个需要,与idisKindOfClass:在那些处理,虽然是一个不同的故事 ......
亚历克斯·格雷

1
@alexgray我明白您的意思, idisKindOfClass:介绍了大多数实际情况。您可能更喜欢重载的原因之一是自动选择了最适合的类型,这将导致使用显式类型检查进行维护的开销很小。
克里斯·哈顿

1
Clang文档明确表示,其作用是为C提供C ++名称处理。这基本上只是编译器通过在幕后自动为Objective-C所做的事情,即通过赋予方法名称以不同的方式包含(以较长的形式)来区别它们参数类型。
克里斯·斯特拉顿

19

David是正确的,因为Objective-C不支持方法重载。从某种意义上说,它类似于PHP。正如他还指出的那样,通常的做法是以示例方式定义具有不同签名的两个或多个方法。但是,也可以使用“ id”类型创建一种方法。通过“ id”类型,可以将任何对象(以及使用NSNumber类的任何基元)发送到方法,然后从方法本身内部可以测试其类型,并在必要时抛出适当的异常。尽管这确实对性能造成了很小的影响,但是除非您要处理大量数据,否则它很可能是名义上的或无关紧要的。

- (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];
    }
}

这也是实现协议以强制对象类型的好地方,可以这样进行:

(id<MyProtocol>)object
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.