Різниця між визначенням @interface у файлах .h та .m


81

Зазвичай ми використовуємо

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

методом у .h файлі та .m файлі ми синтезуємо властивості змінних, оголошених у .h файлі.

Але в коді цей метод @interface ..... @ end також зберігається у файлі .m. Що це означає? Яка різниця між ними?

Також дайте кілька слів про геттери та сеттери для файлу інтерфейсу, який визначено у файлі .m ...

Спасибі заздалегідь

Відповіді:


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 серпня '12: Objective-C розвинувся з часу написання цієї відповіді:

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

це,

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

4
Маленький сиденот, насправді не вкладайте нічого в дужки, коли оголошуєте приватний інтерфейс. В іншому випадку він просто створює категорію, а ви цього не хочете. @interface Person ()вистачить.
Itai Ferber

Дякую itaiferber, я цього не помічав. Я оновив свою відповідь.
Бенедикт Коен,

4
Якщо людям цікаво дізнатись більше про категорії .. ця сторінка була для мене дуже корисною.
Тім

1
Якщо в дужках нічого немає, то це насправді називається class extensionнеcategory
Пол.

5
@ гигант91 Ця відповідь досить стара, і компілятор значно покращився за час, коли він був написаний спочатку. Компілятору більше не потрібна декларація для методу, якщо тіло методу є "видимим". Це означає, що продовження класу ( @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-файлі, але мають дещо іншу поведінку. Ви можете використовувати це в заводських умовах

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.