Когда категории плохие/опасные?

Я использую категории с Core Data. В некоторых учебниках, которые я читал, и лекциях, которые я слушал, говорится, что категории часто считаются «плохой» практикой. Но поскольку Objective-C настолько динамичен, вполне нормально определять методы где-то еще, особенно потому, что можно использовать только общедоступные свойства класса. На какие подводные камни следует обратить внимание при использовании категорий? Или есть какая-то причина, по которой категории на самом деле являются плохой практикой? Причина, по которой я использую их с Core Data, заключается в том, что мне не нужно переписывать мои дополнительные методы каждый раз, когда я заново генерирую подклассы.


person Dustin    schedule 05.07.2012    source источник
comment
Единственный раз, когда я видел какие-либо комментарии против категорий, это когда они использовались в попытке переопределить существующие методы. Если в общем случае они плохи, я подозреваю, что это удивит большое количество разработчиков программного обеспечения Apple, учитывая, как часто они используются в SDK и в примерах кода.   -  person Phillip Mills    schedule 05.07.2012


Ответы (1)


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

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

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

Совет @CodaFi за эту часть документации от Apple:

Хотя язык Objective-C в настоящее время позволяет использовать категорию для переопределения методов, наследуемых классом, или даже методов, объявленных в интерфейсе класса, делать это настоятельно не рекомендуется. Категория не является заменой подкласса. Есть несколько существенных недостатков использования категории для переопределения методов:

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

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

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

Само присутствие некоторых методов категории может привести к изменению поведения во всех фреймворках. Например, если вы переопределяете метод делегата windowWillClose: в категории на NSObject, все делегаты окна в вашей программе затем отвечают, используя метод категории; поведение всех ваших экземпляров NSWindow может измениться. Категории, которые вы добавляете в класс фреймворка, могут вызвать загадочные изменения в поведении и привести к сбоям.

person jrturton    schedule 05.07.2012
comment
Спасибо за ответ, особенно интересна часть о том, какая реализация имеет приоритет. - person Dustin; 05.07.2012