Добавление конфликтующих методов в класс Objective C с использованием category

#objective-c #objective-c-category

#objective-c #objective-c-category

Вопрос:

Я добавил метод foo к классу MYCustomClass в категории Category1 , отдельной от исходного определения класса. Затем я добавил другой метод, также вызываемый foo в другой категории Category2 . Затем я вызываю foo экземпляр MYCustomClass . В моем случае вызывается foo in Category2 . Мой вопрос: есть ли какое-либо объяснение этому? Или это одно из тех «неопределенных» / «зависящих от компилятора» поведений. Кроме того, возможно ли обрабатывать такие ситуации, уточняя вызов метода, указав категорию, которую я хочу использовать в вызове.

РЕДАКТИРОВАТЬ: Я осознаю, что то, что я делаю, не поддерживается. Мне просто интересно, есть ли какой-нибудь способ обойти это.

Ответ №1:

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

Ответ №2:

Это неопределенное поведение. Из документа на языке программирования Objective-C:

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

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

И нет, вы не можете указать, что вы хотите foo из Category1 или foo from Category2 . Если вам это нужно, вы должны дать этим методам разные имена, например foo1 и foo2 .