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

81

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

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

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

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

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

Заранее спасибо

Bgolson
источник

Ответы:

63

Обычно добавляется дополнительная @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 августа 2012 г .: Objective-C эволюционировал с момента написания этого ответа:

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

то есть,

@implementation { 
     id _ivarInImplmentation;
}
//methods
@end
Бенедикт Коэн
источник
4
Небольшое примечание, на самом деле не помещайте ничего в круглые скобки при объявлении частного интерфейса. В противном случае он просто создает категорию, а вы этого не хотите. @interface Person ()будет достаточно.
Итаи Фербер,
Спасибо, itaiferber, я этого не заметил. Я обновил свой ответ.
Бенедикт Коэн,
4
Если людям интересно узнать больше о категориях ... эта страница была мне очень полезна.
Тим
1
Если в скобках ничего нет, то это на самом деле называется « class extensionне а»category
Paul.s
5
@iant91 Этот ответ довольно старый, и компилятор значительно улучшился с того момента, когда он был написан изначально. Компилятору больше не требуется объявление метода, если тело метода «видимое». Это означает, что продолжения класса ( @interface className ()) теперь обычно будут содержать только частные @propertys.
Бенедикт Коэн
10

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

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

@interface Jain:NSObject
{
    NSString *_name;
}

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

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

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

@interface Jain()
    {
        NSString *_name;
    }

    @property(readwrite, copy) NSString *name;
    -(NSString*)makeSmallTalkWith:(Person*)jain;
    @end
Шубхам Джайн
источник
0

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

Энрико Купеллини
источник