2013-06-25 3 views
0

Прежде всего, я новичок в объективе-C. На данный момент я пытаюсь решить следующую задачу:Наследование Objective-C, распространение строк на суперкласс

@interface Animal : NSObject { 
    @private 
    NSString* m_name; 
} 
-(Animal*) initName:(NSString*)name; 
-(void) printName; 

@implementation Animal 
-(Animal*) initName:(NSString*)name { 
    self = [super init]; 
    m_name = name; 
    return self; 
} 
-(void) printName { 
    NSLog(@"%s", m_name); 
} 
@end 

@interface Bird : Animal { 
} 
-(Bird*) initName:(NSString*)name; 

@implementation Bird 
-(Bird*) initName:(NSString*)name { 
    self = [super initName:name]; 
    return self; 
} 
@end 

int main() { 
    Animal* bird = [[Bird alloc] initName:@"abird"]; // warning: assignment from distinct Objective-C type 
    [bird printName]; // prints invalid letters 
    [bird release]; 
} 

Я хочу распространять аргумент конструктора name в суперкласс, но он не работает. Я также попытался напечатать имя внутри конструктора без каких-либо успехов.

Включены все необходимые заголовки. Предупреждение warning: assignment from distinct Objective-C type [enabled by default] при создании объекта дочернего класса является единственным предупреждением, которое я получаю.

Есть ли у кого-нибудь идеи, как я мог бы решить эту проблему?

Привет Dan

+2

Какой компилятор вы используете? Единственное предупреждение, которое я получаю (используя Xcode 4.6.3), - это формат *, который задает тип «char *», но аргумент имеет тип «NSString *» в строке «NSLog (@«% s », m_name);». .. –

+0

@MartinR Да, это странно. Присвоение выражения типа «указатель-подкласс» переменной типа «указатель-суперкласс» должно быть ОК. –

ответ

4

m_name является NSString, не char *. Вы должны зарегистрировать его, используя спецификатор формата %@ вместо %s. Прочтите документацию для строк формата.

Комментарии:

  • Objective-C не C++. Не пытайтесь применять соглашения об именах в стиле C++. Вызовите эту переменную экземпляра name, или animalName, или theName или что угодно. Не называйте это m_name.

  • Инициализаторы условно называются initWithWhatever:, а не initWhatever:. Он лучше отражает цель метода (вы запускаете объект с именем, а не самим именем).

  • Проверьте обратное значение[super init]. Если он вернет nil, ваш инициализатор выйдет из строя. Идиоматическим решением является if (self = [super initWithName:name])

  • Методы инициализации, опять же, возвращаются id.

+0

приятные комментарии, оцените. – viral

+1

@ user0000001 Добро пожаловать. Если вы хотите узнать больше о хорошем стиле Objective-C и соглашениях Cocoa в целом, я предлагаю вам прочитать [Официальные правила Apple по кодированию.] (Http://developer.apple.com/library/mac/#documentation/Cocoa /Conceptual/CodingGuidelines/CodingGuidelines.html) –

+0

Извините за поздний ответ ... Прежде всего спасибо за ваши подсказки, они были действительно полезны! И вы правы. Я должен был распечатать с правильным спецификатором формата. Это решило! Благодаря! – Dan