ios – Objective-C方法签名:参数类型在声明和实现之间可能有所不同吗?

我可以在@interface中声明一个参数类型为NSString *的方法:

- (id) initWithString:(NSString*)str;

而在实现中它是NSNumber *:

- (id) initWithString:(NSNumber*)str

有关完整示例,请参阅下面的代码.当调用[Work test]时,输出是a.x = Hi,所以传入的NSString *经过,可以看到调用了“正确的”initWithString方法.

为什么编译器接受此代码?

参数类型不同时,我可以让编译器抱怨吗?

引用Apple的文档Defining Classes

The only requirement is that the signature matches, which means you must keep the name of the method as well as the parameter and return types exactly the same.

我的测试代码:

@interface ClassA : NSObject

@property (strong, nonatomic) NSNumber *x;

- (id) initWithString:(NSString*)str;
- (void) feed:(NSString*)str;

@end

@implementation ClassA

- (id) initWithString:(NSNumber*)str
{
    self = [super init];
    if (self) {
        self.x = str;
    }
    return self;
}

- (void) feed:(NSNumber*)str
{
    self.x = str;
}

@end


@implementation Work

+ (void) test
{
    ClassA *a = [[ClassA alloc] initWithString:@"Hi"];
    NSLog(@"a.x = %@", a.x);
}

@end

我添加了feed方法来查看它对于类似init的方法是否“特殊”,但编译器也没有抱怨.
(在Yosemite / Xcode 6.4 / iOS8.4模拟器上运行.)

PS:如果我没有使用正确的条款,请纠正我:-)

最佳答案

Can I make the compiler complain when parameter types differ?

有一个警告,您可以通过在标题中包含以下行来激活:

#pragma clang diagnostic error "-Wmethod-signatures"

您还可以将-Wmethod-signature设置到项目的“Other Warning Flags”Xcode构建设置中,以便为整个项目激活它.

我真的不明白为什么Apple在默认情况下如此犹豫要激活这样的有用警告.

几乎每个项目的标准模式都是将“一切”放在“其他警告标志”中.这激活了clang提供的所有警告.

由于有一些警告有点过于迂腐或者没有提供我的编码风格,我会在弹出时单独停用不需要的警告类型.

点赞