Категории на NSObject, обеспечивающие его безопасность

Apple сообщает это:

Категории корневого класса

Категория может добавлять методы к любому классу, включая корневой класс. Методы, добавленные в NSObject, становятся доступными для всех классов, связанных с вашим кодом. Добавление методов к корневому классу с категорией иногда может быть полезным, но также может быть довольно опасным. Хотя может показаться, что модификации, вносимые категорией, хорошо изучены и имеют ограниченное влияние, наследование дает им широкий спектр. Возможно, вы вносите непреднамеренные изменения в невидимые классы в своем приложении; вы можете не знать всех последствий того, что вы делаете. Более того, другие люди, работающие над вашим приложением и не знающие о ваших изменениях, не поймут, что они делают.

Мой вопрос: если я выберу имена методов, которые достаточно странны, и я совершенно уверен, что никто другой не будет их использовать (ни в Apple, ни в моем проекте), могут ли у меня все еще быть проблемы? Может ли быть еще непредвиденное поведение? Влияние на производительность?


person William Jockusch    schedule 14.07.2011    source источник
comment
Objective-C предпочел бы ваш подкласс. Но перестраховываться — для неудачников, верно? ;)   -  person Patrick Perini    schedule 14.07.2011


Ответы (2)


Если вы действительно совершенно уверены, что Apple никогда не добавит метод с таким именем, это безопасно. Однако если вы хотите обеспечить соблюдение этой уверенности, добавьте префикс имени селектора. Например, Adium в какой-то момент добавил метод -setObject:atIndex: к NSMutableArray (да, просто "косметическая" обертка поверх существующего API-метода -replaceObject:atIndex. Очень бессмысленно)... оказалось, что он имеет то же имя, что и внутренний метод, и оооочень немного другая семантика. Это вызывало сбои, но только на определенных ОС. Если бы его назвали как-нибудь вроде -AISetObject:atIndex:, все было бы в порядке.

Последствия производительности для категорий минимальны. Я бы не беспокоился об этом аспекте.

person Catfish_Man    schedule 14.07.2011
comment
Это не просто система. Один отчет о сбое в методе категории -[NSDictionary setDoubleValue:forKey:] оказался конфликтом с диспетчером ввода, который реализовал метод с тем же именем, но, по-видимому, ожидал объекта в качестве параметра Double:. Диспетчер ввода использовался для внедрения кода в iChat, но, по-видимому, загрузил полный хак в каждое приложение, включая его категории Foundation. - person Jens Ayton; 14.07.2011
comment
Я думаю, AISetObject больше не был бы очень косметическим :-) - person Joris Weimar; 15.05.2012

Если имена ваших методов ни с чем не конфликтуют, и люди, которые их используют, знают, что они делают, у вас не должно возникнуть никаких проблем. Помните, что категория добавляет в класс дополнительные методы, но не переменные экземпляра. Подкласс является более гибким и рассматривается как целый объект, который реагирует на все методы суперкласса, а также на свой собственный. Я бы сказал, создайте подкласс, если вы не можете или неудобно это делать. В конце концов, категории были созданы для того, чтобы ими пользовались. Я обычно использую категории, когда у меня есть фреймворк и мне нужно добавить частные методы в публично объявленный класс.

person Greg    schedule 14.07.2011