Есть ли хороший / наилучший способ расширить вложенный класс в Objective-C?

#iphone #objective-c #cocoa-touch #cocoa #cocoa-design-patterns

#iPhone #objective-c #cocoa-touch #cocoa #cocoa-design-patterns

Вопрос:

Иногда объекты фреймворка помещают интерфейсы вспомогательного класса внутрь файлов *.m, таких как:

Foo.m:

 @interface HelperObject : NSObject
/*...*/
@end
@implementation HelperObject
/*...*/
@end

@implementation Foo
/*...*/
@end
  

Если я хочу расширить Foo, например, используя категорию, есть ли способ расширить HelperObject также? В более общем плане, является ли это нарушением инкапсуляции? Должен ли я попытаться расширить функциональность класса без расширения HelperObject?

Ответ №1:

Вызывающие его пользователи Foo ничего не знают о HelperObject — часто они даже не подозревают о его существовании. Итак, небезопасно или допустимо добавлять его в подкласс в другом файле.

Ответ №2:

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

В общем случае Objective-C не поддерживает множественное наследование ни классов, ни категорий.

Однако он поддерживает множественное наследование интерфейсов через протоколы.

То есть вы могли бы объявить протокол в вашем .m файле, который реализуют как Helper, так и Foo .

Ответ №3:

Objective C не допускает вложенных классов (в отличие, например, от Java или C ). Вы можете использовать агрегацию для расширения функциональности классов. Если вы хотите что-то скрыть, вы можете использовать идиому Pimpl, однако в ObjC это необязательно, потому что вы можете легко заменить это на category .

Редактировать: если вы хотите расширить объект HelperObject с помощью category, вы должны объявить его в том же файле, где вы хотите использовать эти функции (чтобы они были видны).