2011-12-30 1 views
0

DataController.hДва интерфейса?

@class Play; 

@interface DataController : NSObject 

- (unsigned)countOfList; 
- (Play *)objectInListAtIndex:(unsigned)theIndex; 

@end 

DataController.m

#import "DataController.h" 
#import "Play.h" 


@interface DataController() 
@property (nonatomic, copy, readwrite) NSMutableArray *list; 
- (void)createDemoData; 
@end 


@implementation DataController 

@synthesize list; 


- (id)init { 
    if (self = [super init]) { 
     [self createDemoData]; 
    } 
    return self; 
} 

Почему вы думаете, что @interface определяется в два раза? А также что означает()? Не должно ли быть классное имя, возможно, суперкласс между круглыми скобками?

+1

См http://stackoverflow.com/questions/862299/how- do-a-category-work-in-objective-c – XJones

ответ

7

В целом синтаксис @interface ClassName (CategoryName) предназначен для объявления категории. Категории - это способ добавления методов в класс. Вы можете сделать это даже с классами, для которых у вас нет исходного кода. См. Больше here.

@interface ClassName() (без ничего в круглых скобках) по существу является особым случаем категории и называется расширением класса. Основное различие между расширением класса и категорией состоит в том, что методы, объявленные в расширении класса, должны быть определены/реализованы в основном блоке @implementation для класса или вы получите предупреждение о компиляторе. Методы в обычной категории могут быть определены во внешнем блоке @implementation.

Наиболее распространенное использование расширений класса (как в данном случае) для объявления частных методов. Objective-C не поддерживает истинные частные методы, поэтому простой способ добиться того же базового конечного результата - объявить частные методы в расширении класса в верхней части файла .m. Поскольку эти методы не определены в файле .h, другие классы их не видят, и вы получите предупреждение о компиляторе, если попытаетесь использовать их вне класса, к которому они принадлежат.

Вы также можете обновить readonly @property как readwrite в расширении класса. Таким образом, код, внешний по отношению к реализации класса, может читать только значение свойства, но внутри реализации класса вы также можете написать ему. Это единственный случай, когда разрешено переопределять @property.

(Обратите внимание, что расширения классов были новая функция в Objective-C 2.0 и не доступны на Mac OS X 10.4 и более ранних версий.)

+1

Вы указываете ** redeclaring ** '@ property' для изменения сгенерированных аксессуаров, но вы не упомянули, что можете просто ** объявить **' @ property' в расширения класса. –

+0

Это отличный ответ, однако я бы изменил '@interface ClassName (ProtocolName)' на '@interface ClassName (CategoryName)', чтобы избежать путаницы между категориями и протоколами. – EmilioPelaez

+0

@ EmilioPelaez, который был немой опечаткой, и я исправил его. Спасибо, что поймали его. Возможно, стоит упомянуть, что категории иногда используются для объявления неофициальных протоколов ... –

Смежные вопросы