Почему @interface выше @implementation?

Мне интересно, почему дважды @interface. Один в class.h, другой в class.m. Например:

TestTableViewController.h:

#import <UIKit/UIKit.h>

@interface TestTableViewController : UITableViewController

@end

и (автоматически генерируется) class.m я нахожу:

#import "TestTableViewController.h"

@interface TestTableViewController ()

@end

@implementation TestTableViewController

... methods delegated from UITable delegates

@end

Итак, мой вопрос в том, о чем @interface TestTableViewController () в файле .m. Почему это там? Мне это нужно?

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


person Matej    schedule 21.07.2012    source источник


Ответы (4)


Вторая директива @interface находится в файле реализации (.m) — из нее можно сделать вывод, что она предназначена для объявления вещей, которые создатель класса не хотел показывать пользователю класса. Обычно это означает частные и/или внутренние методы и свойства. Также обратите внимание, что есть два типа выполнения этого. Тот (который вы видите здесь) называется «расширением класса» и обозначается пустой парой круглых скобок:

@interface MyClass ()

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

Второй, называемый «категорией», обозначается непустой парой скобок, заключающих в себя имя категории, например:

@interface MyClass (CategoryName)

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

person Community    schedule 21.07.2012

Второй «интерфейс» определяет расширение для класса «TestTableViewController», которое невидимо для тех, кто только импортирует h-файл. Это де-факто способ создания приватных методов в объектном C.

person dcoder    schedule 21.07.2012
comment
Нет, это не категория, это расширение класса. -1. - person ; 21.07.2012
comment
Не очень хорошо с -1. Разница между категориями и расширениями в основном семантическая: расширение в основном является анонимной категорией, требующей его реализации в основном блоке реализации класса. Таким образом, установка имени в скобках второго блока интерфейса фактически создаст категорию, а не расширение... - person dcoder; 22.07.2012

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

person DrummerB    schedule 21.07.2012

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

Обычный интерфейс категории выглядит так:

@interface TestTableViewController (Your_Category_Name)
- (void)doSomething;
@end

И соответствующая реализация:

@implementation TestTableViewController (Your_Category_Name)
-(void)doSomething {
// Does something...
}
@end

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

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

person Sandro Meier    schedule 21.07.2012
comment
Полезно ли использование категорий для чего-либо, кроме объявления приватных методов и категоризации кода? - person Matej; 21.07.2012
comment
Спасибо что сказал мне. Я не знал, что это называется расширением класса. Я просто думал об этом как о категории до сих пор. Я починю это. - person Sandro Meier; 21.07.2012
comment
Даже если нет имени, класс все равно не расширяется? Как мы можем добавить переменные экземпляра? - person Honey; 28.03.2016
comment
Вам нужно использовать среду выполнения ObjC. Взгляните на этот ответ: stackoverflow.com/a/13757149/262534 - person Sandro Meier; 31.03.2016