Я использую категории с Core Data. В некоторых учебниках, которые я читал, и лекциях, которые я слушал, говорится, что категории часто считаются «плохой» практикой. Но поскольку Objective-C настолько динамичен, вполне нормально определять методы где-то еще, особенно потому, что можно использовать только общедоступные свойства класса. На какие подводные камни следует обратить внимание при использовании категорий? Или есть какая-то причина, по которой категории на самом деле являются плохой практикой? Причина, по которой я использую их с Core Data, заключается в том, что мне не нужно переписывать мои дополнительные методы каждый раз, когда я заново генерирую подклассы.
Когда категории плохие/опасные?
Ответы (1)
Единственная опасность, о которой я могу думать, - это когда вы используете их для замены методов в исходном классе, а не для подкласса.
При этом вы теряете возможность доступа к исходной реализации, которая, поскольку обычно вы переопределяете закрытый метод, может иметь непредвиденные последствия.
Использование категорий для добавления дополнительных методов к любому объекту определенного класса — это здорово, и именно для этого они и предназначены. Использование их для основных данных, как вы делаете, прекрасно, потому что это позволяет вам изменить вашу модель и регенерировать ванильный объект, не уничтожая какой-либо дополнительный код.
Совет @CodaFi за эту часть документации от Apple:
Хотя язык Objective-C в настоящее время позволяет использовать категорию для переопределения методов, наследуемых классом, или даже методов, объявленных в интерфейсе класса, делать это настоятельно не рекомендуется. Категория не является заменой подкласса. Есть несколько существенных недостатков использования категории для переопределения методов:
Когда категория переопределяет унаследованный метод, метод в категории, как обычно, может вызывать унаследованную реализацию через сообщение super. Однако, если категория переопределяет метод, существующий в классе категории, невозможно вызвать исходную реализацию.
Категория не может надежно переопределить методы, объявленные в другой категории того же класса.
Этот вопрос имеет особое значение, поскольку многие классы Cocoa реализованы с использованием категорий. Определенный платформой метод, который вы пытаетесь переопределить, может сам быть реализован в категории, поэтому не определено, какая реализация имеет приоритет.
Само присутствие некоторых методов категории может привести к изменению поведения во всех фреймворках. Например, если вы переопределяете метод делегата windowWillClose: в категории на NSObject, все делегаты окна в вашей программе затем отвечают, используя метод категории; поведение всех ваших экземпляров NSWindow может измениться. Категории, которые вы добавляете в класс фреймворка, могут вызвать загадочные изменения в поведении и привести к сбоям.