Мне было интересно, как подавить предупреждение:
Категория реализует метод, который также будет реализован его основным классом.
У меня есть это для конкретной категории кода:
+ (UIFont *)systemFontOfSize:(CGFloat)fontSize {
return [self aCustomFontOfSize:fontSize];
}
objective-c
clang
Doz
источник
источник
super
противном случае.Ответы:
Категория позволяет добавлять новые методы в существующий класс. Если вы хотите повторно реализовать метод, который уже существует в классе, вы обычно создаете подкласс вместо категории.
Документация Apple: настройка существующих классов
Два метода с одной и той же сигнатурой в одном классе могут привести к непредсказуемому поведению, поскольку каждый вызывающий объект не может указать, какую реализацию они хотят.
Итак, вы должны либо использовать категорию и предоставить имена методов, которые являются новыми и уникальными для класса, либо подкласс, если вы хотите изменить поведение существующего метода в классе.
источник
Хотя все сказанное правильно, на самом деле это не отвечает на ваш вопрос о том, как подавить предупреждение.
Если вам по какой-то причине нужен этот код (в моем случае у меня есть HockeyKit в моем проекте, и они переопределяют метод в категории UIImage [изменить: это уже не так]), и вам нужно, чтобы ваш проект скомпилировался , вы можете использовать
#pragma
инструкции для блокировки предупреждения, например:Я нашел информацию здесь: http://www.cocoabuilder.com/archive/xcode/313767-disable-warning-for-override-in-category.html
источник
Лучшая альтернатива (см. Ответ bneely о том, почему это предупреждение спасает вас от катастрофы) - использовать метод swizzling. Используя смену метода, вы можете заменить существующий метод из категории без неопределенности в том, кто «выиграет», и при этом сохраняя возможность вызова старого метода. Секрет в том, чтобы дать переопределению другое имя метода, а затем поменять их местами с помощью функций времени выполнения.
Затем определите свою индивидуальную реализацию:
Замените реализацию по умолчанию на вашу:
источник
Попробуйте это в своем коде:
ОБНОВЛЕНИЕ 2: Добавьте этот макрос
источник
Вы можете использовать swizzling для подавления этого предупреждения компилятора. Вот как я реализовал swizzling метода для рисования полей в UITextField, когда мы используем настраиваемый фон с UITextBorderStyleNone:
источник
Переопределяющие свойства действительны для расширения класса (анонимная категория), но не для обычной категории.
Согласно Apple Docs, используя расширение класса (анонимная категория), вы можете создать частный интерфейс для общедоступного класса, так что частный интерфейс может переопределить публично открытые свойства. т.е. вы можете изменить свойство с "только чтение" на "чтение-запись".
Пример использования для этого - когда вы пишете библиотеки, которые ограничивают доступ к общедоступным свойствам, в то время как для того же свойства требуется полный доступ для чтения и записи в библиотеке.
Ссылка на Apple Docs: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html
Найдите « Используйте расширения класса, чтобы скрыть личную информацию ».
Таким образом, этот метод действителен для расширения класса, но не для категории.
источник
Категории - это хорошо, но ими можно злоупотреблять. При написании категорий вы, как правило, НЕ должны повторно реализовывать методы выхода. Это может вызвать странный побочный эффект, поскольку вы сейчас переписываете код, от которого зависит другой класс. вы можете сломать известный класс и в конечном итоге вывернуть отладчик наизнанку. Это просто плохое программирование.
Если вам нужно это сделать, вам действительно следует создать подкласс.
Тогда предложение выпить, это большой НЕТ-НЕТ-НЕТ для меня.
Свизинг во время выполнения - это полное НЕТ-НЕТ-НЕТ.
Вы хотите, чтобы банан выглядел как апельсин, но только во время выполнения? Если хотите апельсин, напишите апельсин.
Не делайте банан похожим на апельсин. И что еще хуже: не превращайте свой банан в секретного агента, который будет незаметно саботировать бананы по всему миру в поддержку апельсинов.
Ой!
источник
У меня возникла эта проблема, когда я реализовал метод делегата в категории, а не в основном классе (хотя реализации основного класса не было). Решение для меня заключалось в том, чтобы переместить из главного файла заголовка класса в файл заголовка категории. Это отлично работает
источник