2010-07-11 4 views
12

Я знаю несколько правил в отношении категорий Objective-C:Что произойдет, если две категории ObjC переопределяют один и тот же метод?

  1. метода Категория не должна переопределять существующие методы (класс или экземпляр)
  2. Два различных категории, реализующие один и тот же метод для того же класс приведет к непредсказуемому поведению

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

@interface NSView (MyExtensions) 
- (void)foo; // NSView category implementation 
@end 

@interface MyClass : NSView 
{ } 
@end 

@interface MyClass (MyExtensions) 
- (void)foo; // MyClass category implementation 
@end 

С этими интерфейсами определен, какой метод будет выполняться при запуске следующего кода?

MyClass * instance = [[MyClass alloc] initWith...]; 
[instance foo]; 
[instance release]; 

Примечание: С моим компилятором, реализация MyClass имеет преимущество, но я не уверен, что гарантированно произойдет, или просто один специфический вкус неопределенного поведения.

ответ

12

Каждый метод каждого класса имеет реализацию. Категория добавляет или заменяет метод для определенного класса. Это означает поведение, которое вы видите, где MyClass имеет один foo, а NSView имеет еще один foo. Любой экземпляр MyClass будет иметь другой foo, чем любой экземпляр NSView, который не является MyClass, как если бы foo был определен в основной реализации, а не в категории. Вы даже можете позвонить [super foo] из MyClass, чтобы получить доступ к foo, определенному для NSView.

+3

Правильно ли переопределить метод Category, объявленный и реализованный в категории суперкласса? – BergP

32

Чтобы продлить на drawnonward ответ:

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

Все, что вы могли бы сделать в обычном интерфейсе класса, который вы можете сделать в категории, и ничего, что вы не должно делать в обычном интерфейсе класса, который вы не должны делать в категории.

Итак:

метода Категория не должна отменять существующих метод (класс или экземпляр)

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

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

две различные категории, реализующие те же метод приводит к неопределенному поведение

Это должно быть переписано, чтобы сказать «две различные категории, реализующие один и тот же метод для того же класса результаты неопределенными поведение." Опять же, потому что все методы для любого одного класса попадают в один и тот же файл, имея два метода в одном классе, очевидно, вызывают странность.

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

Если вы когда-либо путались о том, приведет ли категория к проблеме, просто спросите себя: «Будут ли методы в категории работать, если я скопировал и вложил их все в файлы« .h/.m »класса?» Если ответ «да», значит, вы поняли. Если «нет», то у вас проблемы.

+2

+1 Спасибо. Это очень хороший способ описать это. Я также изменил формулировку правила № 2, чтобы соответствовать вашим требованиям. –

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

  • Нет связанных вопросов^_^