【问题标题】:Objective-C error "No visible @interface for 'XYZPerson' declares the selector 'saySomething'Objective-C 错误“‘XYZPerson’没有可见的@interface 声明选择器‘saySomething’
【发布时间】:2013-02-04 01:29:45
【问题描述】:

我对 Objective-C 非常陌生,当我练习书本练习时,我真的被困在这里。请帮我解决这个问题,我一直在思考可能导致此错误的原因超过三个小时。还是没看懂!

最好的问候, 拉吉。

提前致谢!

ma​​in.m

#import <Foundation/Foundation.h>
#import "XYZPerson.h"
#import "XYZShout.h"
int main(int argc, const char * argv[])
{

    @autoreleasepool {

        //XYZPerson *some = [[XYZPerson alloc]init];

        XYZShout *some = [[XYZShout alloc]init];
        [some sayHello];



        // insert code here...
       // NSLog(@"Hello, World!");

    }
    return 0;
}

XYZPerson.h

#import <Foundation/Foundation.h>
@interface XYZPerson : NSObject

@property NSString *firstName;
@property NSString *secondName;
@property NSDate *dob;

-(void) saySomething;
-(void) sayHello;

@end

XYZPerson.m

#import "XYZPerson.h"
@implementation XYZPerson

-(void) sayHello {
    [self saySomething:@"Hello all"];
}

-(void) saySomething:(NSString *)greet {
    NSLog(@"%@", greet);
}

@end

XYZShout.h

#import "XYZPerson.h"

@interface XYZShout : XYZPerson

// -(void) saySomething;

@end

XYZShout.m

#import "XYZShout.h"

@implementation XYZShout

-(void) saySomething:(NSString *)greet {
    NSString *upperGreet = [greet uppercaseString];
    [super saySomething:upperGreet];    // this is where I get the error mentioned above
}

@end

搞定了!感谢@MatthewD、@trojanfoe、@JFS 的大力帮助:)

【问题讨论】:

  • 能否也包含 XYZShout.h 的代码?
  • 如果将 XYZPerson.h 中的 - (void) saySomething; 更改为 - (void) saySomething:greet; 会发生什么?
  • 添加了 XYZShout.h MatthewD
  • 现在将尝试您的建议..
  • MatthewD... :) 它起作用了.. 现在我输入大写了 :) 为什么当我将其更改为 saySomething:greet 而不是 saySomething 时它会运行?由于 greet 仅与“saySomething”一起定义!

标签: objective-c selector superclass


【解决方案1】:

(从 cmets 移至答案...)

MatthewD:如果将 - (void) saySomething; 中的 XYZPerson.h 更改为 - (void) saySomething:greet;,会发生什么?

Raj0689:为什么当我将其更改为 saySomething:greet 而不是 saySomething 时它会运行?由于 greet 仅与 saySomething 一起定义!!

当您调用一个方法时,编译器需要找到该方法的签名,以便验证该方法是否被正确调用。签名包括方法名称以及参数的数量和类型。提供方法签名的常用方法是导入定义这些签名的头文件。

所以,在你打电话的XYZShout.m

[super saySomething:upperGreet];

编译器搜索由XYZShout.m 导入的XYZShout.h 和由XYZShout.h 导入的XYZPerson.h。在XYZShout.h中,发现如下方法:

-(void) saySomething;

这在名称上匹配被调用的方法,但在参数上不匹配,因此编译器不认为这是匹配。在任何地方都找不到saySomething 的其他定义,因此它会给出错误。

【讨论】:

    【解决方案2】:

    请确保将XYZShout.h接口设置为@interface XYZShout : XYZPerson

    【讨论】:

    • @JFS 不要将问题作为答案。
    • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时评论自己的帖子,一旦您有足够的reputation,您就可以comment on any post
    • +1 因为这基本上是正确的。大力水手和 mipe34;不要那么挑剔。
    • @Popeye,感谢您的提示,但是当我发布我的问题时并不明显。 user2029446 在我的问题之后添加了 XYZShout.h 部分。请不要对帮助人民投反对票。
    • @trojanfoe:非常感谢!您的详细答案肯定会好得多。感谢您的公平。
    【解决方案3】:

    看起来您正在测试继承,所以我假设XYZShout 应该派生自XYZPerson。如果是这样,请遵循@JFS 的建议并确保它确实派生:

    XYZShout.h:

    #import <Foundation/Foundation.h>
    #import "XYZPerson.h"
    
    @interface XYZShout : XYZPerson
    
    - (void)saySomething:(NSString *)greet;
    
    @end
    

    同时更正XYZPersonsaySomething的定义(你漏掉了参数):

    XYZPerson.h:

    #import <Foundation/Foundation.h>
    @interface XYZPerson : NSObject
    
    @property NSString *firstName;
    @property NSString *secondName;
    @property NSDate *dob;
    
    - (void)saySomething:(NSString *)greet;
    //                   ^^^^^^^^^^^^^^^^^
    - (void)sayHello;
    
    @end
    

    【讨论】:

    • 非常感谢 :) 真的很有帮助 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-05
    • 2017-10-25
    相关资源
    最近更新 更多