Разница между определением @interface в файлах .h и .m

#ios #objective-c #class #implementation #convenience-methods

#objective-c #интерфейс #заголовочные файлы #сеттер #средство получения

Вопрос:

Обычно мы используем

 @interface interface_name : parent_class <delegates>
{
......
}
@end 
  

методом в файлах .h и .m мы синтезируем свойства переменных, объявленных в файле .h.

Но в некотором коде это @interface…..@end метод также хранится в файле .m. Что это значит? В чем разница между ними?

Также дайте несколько слов о геттерах и сеттерах для файла интерфейса, который определен в файле .m…

Ответ №1:

Обычно добавляется дополнение @interface , определяющее категорию, содержащую частные методы:

Person.h:

 @interface Person
{
    NSString *_name;
}

@property(readwrite, copy) NSString *name;
-(NSString*)makeSmallTalkWith:(Person*)person;
@end
  

Person.m:

 @interface Person () //Not specifying a name for the category makes compiler checks that these methods are implemented.

-(void)startThinkOfWhatToHaveForDinner;
@end


@implementation Person

@synthesize name = _name;

-(NSString*)makeSmallTalkWith:(Person*)person
{
    [self startThinkOfWhatToHaveForDinner];
    return @"How's your day?";
}


-(void)startThinkOfWhatToHaveForDinner
{

}

@end
  

«Частная категория» (правильное имя для безымянной категории — это не «частная категория», а «расширение класса») .m не позволяет компилятору предупреждать о том, что методы определены. Однако, поскольку @interface в файле .m это категория, вы не можете определить в ней ivars.

Обновление 6 августа ’12: Objective-C изменился с момента написания этого ответа:

  • ivars может быть объявлено в расширении класса (и всегда могло быть — ответ был неправильным)
  • @synthesize не требуется
  • ivars теперь может быть объявлено в фигурных скобках в верхней части @implementation :

это,

 @implementation { 
     id _ivarInImplmentation;
}
//methods
@end
  

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

1. Небольшое примечание, на самом деле ничего не помещайте в круглые скобки при объявлении частного интерфейса. В противном случае это просто создаст категорию, а вам это не нужно. @interface Person () будет достаточно.

2. Спасибо itaiferber, я этого не заметил. Я обновил свой ответ.

3. Если людям интересно узнать больше о категориях.. эта страница была очень полезна для меня.

4. Если в скобках ничего нет, то это на самом деле называется class extension не a category

5. @giant91 Этот ответ довольно старый, и компилятор значительно улучшился с момента его первоначального написания. Компилятору больше не нужно объявление для метода, если тело метода является «видимым». Это означает, что продолжения класса ( @interface className () ) обычно теперь будут содержать только частные @property s .

Ответ №2:

Концепция заключается в том, что вы можете сделать свой проект намного чище, если вы ограничите .h общедоступными интерфейсами вашего класса, а затем добавите частные детали реализации в это расширение класса.

когда вы объявляете переменные методы или свойства в файле ABC.h , это означает, что к этим свойствам переменных и методам можно получить доступ за пределами класса

 @interface Jain:NSObject
{
    NSString *_name;
}

@property(readwrite, copy) NSString *name;
-(NSString*)makeSmallTalkWith:(Person*)jain;
@end
  

@Interface позволяет объявлять частные переменные, свойства и
методы. Таким образом, все, что вы объявляете здесь, не может быть доступно извне
этого класса. В общем, вы хотите объявить все переменные, свойства и
методы по умолчанию закрытыми

Просто скажите, когда вы объявляете переменные методы или свойства в файле ABC.m , это означает, что к этим свойствам переменных и методам нельзя получить доступ за пределами класса

 @interface Jain()
    {
        NSString *_name;
    }

    @property(readwrite, copy) NSString *name;
    -(NSString*)makeSmallTalkWith:(Person*)jain;
    @end
  

Ответ №3:

вы даже можете создавать другие классы в файле .m, например, другие небольшие классы, которые наследуют от класса, объявленного в файле .h, но имеют несколько иное поведение. Вы могли бы использовать это в заводском шаблоне