Каков наилучший способ решить коллизию пространства имен Objective C? - PullRequest
173 голосов
/ 07 октября 2008

Objective-C не имеет пространств имен; это очень похоже на C, все находится в одном глобальном пространстве имен. Обычной практикой является добавление классов к инициалам, например если вы работаете в IBM, вы можете поставить перед ними префикс «IBM»; если вы работаете в Microsoft, вы можете использовать «MS»; и так далее. Иногда инициалы относятся к проекту, например, Adium использует префиксы классов с "AI" (так как за этим нет никакой компании, которую вы могли бы взять инициалы). Apple префиксирует классы с NS и говорит, что этот префикс зарезервирован только для Apple.

Пока все хорошо. Но добавление от 2 до 4 букв к имени класса впереди - очень и очень ограниченное пространство имен. Например. MS или AI могут иметь совершенно разные значения (например, AI может быть искусственным интеллектом), и некоторые другие разработчики могут решить использовать их и создать класс с одинаковым именем. Взрыв , столкновение пространства имен.

Хорошо, если это коллизия между одним из ваших собственных классов и одним из используемых вами внешних фреймворков, вы можете легко изменить наименование вашего класса, ничего страшного. Но что, если вы используете две внешние платформы, обе из которых у вас нет исходного кода и которые вы не можете изменить? Ваше приложение связывается с ними обоими, и вы получаете конфликт имен. Как бы вы решили это? Каков наилучший способ обойти их таким образом, чтобы вы все еще могли использовать оба класса?

В C вы можете обойти это, не связываясь напрямую с библиотекой, вместо этого вы загружаете библиотеку во время выполнения, используя dlopen (), затем находите искомый символ с помощью dlsym () и назначаете его глобальному символу. (что вы можете назвать как угодно), а затем получить к нему доступ через этот глобальный символ. Например. если у вас есть конфликт, потому что в некоторой библиотеке C есть функция с именем open (), вы можете определить переменную с именем myOpen и указать ей функцию open () библиотеки, таким образом, когда вы хотите использовать систему open (), вы просто используете open (), а когда вы хотите использовать другой, вы получаете к нему доступ через идентификатор myOpen.

Возможно ли нечто подобное в Objective-C, а если нет, то есть ли какое-нибудь другое умное, хитрое решение, которое вы можете использовать для разрешения конфликтов пространства имен? Есть идеи?


Обновление:

Просто чтобы прояснить это: ответы, которые предлагают, как избежать конфликтов пространства имен заранее или как создать лучшее пространство имен, безусловно, приветствуются; однако я не приму их как ответ , поскольку они не решают мою проблему. У меня есть две библиотеки, и их имена классов сталкиваются. Я не могу их изменить; У меня нет источника ни того, ни другого. Столкновение уже произошло, и советы о том, как его можно было избежать заранее, больше не помогут. Я могу направить их разработчикам этих фреймворков и надеюсь, что в будущем они выберут лучшее пространство имен, но сейчас я ищу решение для работы с фреймворками прямо сейчас в одном приложении. Какие-нибудь решения, чтобы сделать это возможным?

Ответы [ 13 ]

0 голосов
/ 20 мая 2012

Если столкновение происходит только на уровне статической связи, вы можете выбрать, какая библиотека используется для разрешения символов:

cc foo.o -ldog bar.o -lcat

Если foo.o и bar.o оба ссылаются на символ rat, тогда libdog разрешит foo.o rat, а libcat разрешит bar.o * rat.

0 голосов
/ 01 марта 2009

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

Более техническое решение, если бы я был на вашем месте, это был бы мой выбор.

0 голосов
/ 07 октября 2008

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

http://www.cocoadev.com/index.pl?ChooseYourOwnPrefix

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...