2013-11-26 3 views
0

Я начинаю Objective C, пытаясь написать простую программу, напечатать год рождения человека, но есть ошибка «Несколько методов с именем« setYear », найденные с помощью результат несоответствия ", может ли кто-нибудь помочь мне разобраться, почему это происходит?Множество методов с именем «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; 

}

+1

Одна ошибка заключается в том, что * year * является свойством int. Но вы передаете * NSNumber * в метод * setYear: *. – EmptyStack

+0

hi @EmptyStack, как присвоить значение году? Благодарю. – wuyefeibao

+0

Измените эту строку на *** [aperson setYear: 1970]; ***. Обратите внимание, что @ удаляется. – EmptyStack

ответ

3

Плохая идея использовать тип id для переменных, если вы знаете, какой тип вы собираетесь туда поместить. Это связано с тем, что с помощью id вместо реального имени класса компилятор просто не знает, какие проверки работоспособности выполняются.

В данном конкретном случае, компилятор видит метод setYear:, но так как он не знает, что должно быть person объект (пожалуйста, придерживайтесь именования Objective-C и переименовать класс в Person вместо), он смотрит вверх все методы, называемые setYear:, могут найти. Он найдет ваше имущество типа int, но он также найдет -[NSDateComponents setYear:], который ожидает NSInteger, который является либо int, либо long. Если вы создаете для 64-битного, это будет long.

Итак, теперь компилятор знает, что существует два метода: setYear:, ожидается int, а другой a long. Компилятор не знает, что вы имеете в виду, так как тип aperson равен id.

Существует два решения: либо поставить бросок в вызов, как в [(person *)aperson setYear:1970] (минус @1970, что является NSNumber, здесь не так). Лучшее решение - фактически рассказать компилятору о своем намерении и указать правильный тип переменной:

person *aperson = [person person]; 
[person setYear:1970]; 
+0

Ваши объяснения настолько ясны! Спасибо огромное! – wuyefeibao

1

Вы можете решить эту проблему путем коррекции вызова setYear: метода. Ваш код в основном методе должен выглядеть следующим образом:

int main(){ 
    @autoreleasepool { 
     id aperson = [person person]; 
     [(person*)aperson setYear:1970]; 
     NSLog (@"Birth year: %@", [aperson summary]); 
    } 
return 0; 
} 

Вашей проблема становится решена путем замены идентификатора с правильным типом отправителя (лицо * в данном случае), потому что компилятор будет знать, что отправитель является экземпляром класс человека, и поэтому знает, какой метод setYear: применяется здесь.

+0

Привет @Vinay Jain, это решение работает, если я изменяю свойство 'year' на' NSNumber', но если это 'int', это не работает. – wuyefeibao

+0

Будет работать, просто удалите «@» с номера «1970». –

+0

Он работает, спасибо! Но я до сих пор не понимаю, почему. Например, если у меня есть свойство '@property NSString * name;', то почему я могу использовать '[aperson setName: @" Tom "];' для установки, но для чисел я не могу – wuyefeibao