我是Objective C的初学者,试图编写一个简单的程序打印一个人的出生年份,但是有一个错误“多个方法命名为'setYear'找到了不匹配的结果”,任何人都可以帮我搞清楚为什么会这样?
//person.h
@interface person : NSObject
@property int year;
+ (id)person;
@property (readonly) NSString* summary;
@end
// main.m
#import "person.h"
@implementation person
@synthesize year;
+ (id)book{
person *somePerson = [[self alloc] init];
return somePerson;
}
- (NSString*)summary{
NSNumber* yearAsObject;
yearAsObject = [NSNumber numberWithInteger:self.year];
return [NSString stringWithFormat:@"Borned in %@.", yearAsObject];
}
@end
int main(){
@autoreleasepool {
id aperson = [person person];
[aperson setYear:@1970];
NSLog (@"Birth year: %@", [aperson summary]);
}
return 0;
}
答案 0 :(得分:3)
如果您知道要放置哪种类型,那么在变量上使用id
类型是个坏主意。那是因为通过使用id
而不是真正的类名,编译器根本不知道要执行什么样的完整性检查。
在这种特殊情况下,编译器会看到方法setYear:
,但由于它不知道它应该是person
对象(请坚持Objective-C命名约定并将类重命名为{ {1}}代替它,它查找它可以找到的所有方法Person
。它会找到setYear:
类型的属性,但它也会找到-[NSDateComponents setYear:]
,其中int
需要NSInteger
或int
。如果您正在构建64位,那么它将是long
。
现在编译器知道存在两种方法long
,一种方法需要setYear:
,另一种方法需要int
。{}由于long
的类型为aperson
,编译器不知道您的意思。
有两种解决方案:要么像id
那样在广告中投放广告投放(传递[(person *)aperson setYear:1970]
,这是@1970
,这里错了)。更好的解决方案是实际告诉编译器您的意图并指定变量的正确类型:
NSNumber
答案 1 :(得分:1)
您可以通过更正setYear:
方法调用来解决此问题。 main方法中的代码应如下所示:
int main(){
@autoreleasepool {
id aperson = [person person];
[(person*)aperson setYear:1970];
NSLog (@"Birth year: %@", [aperson summary]);
}
return 0;
}
你的问题通过用正确类型的发送者(在这种情况下是人*)替换id来解决,因为编译器然后知道发送者是person类的一个实例,因此知道哪个setYear:
方法在这里应用。