Определено ли поведение для изменения isa объекта Objective-C?

В Objective-C вы можете изменить динамический тип объекта во время выполнения, назначив его isa переменной-члену:

id object = ...;
object->isa = [SomeClass class];

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


person Adam Rosenfield    schedule 17.02.2009    source источник
comment
возможный дубликат Objective-C: Как изменить класс объекта во время выполнения?   -  person Gabriele Petronella    schedule 28.08.2013
comment
Вы можете столкнуться с проблемами с КВО. Они также используют isa-swizzling. Однако у Майка Эша есть полное решение: mikeash.com/pyblog/   -  person nielsbot    schedule 28.08.2013


Ответы (4)


Я думаю, что это, как вы говорите, грязно.

Я подозреваю, что это сработает, если:

  • Вновь назначенный класс является подклассом реального класса.
  • Новый класс не добавляет никаких переменных-членов.

Но я признаю, что не знаю основ реализации вашей системы выполнения Objective-C. Я просто знаю, что имеет смысл для меня для реализации.

person Darron    schedule 17.02.2009

Среда выполнения Objective-C теперь предоставляет для этого функцию: object_setClass. В документации не сказано, какие существуют ограничения, но (как уже говорили другие) я предполагаю, что вы захотите ограничить новый класс классом с точно такой же компоновкой переменной экземпляра, как исходный класс.

person benzado    schedule 28.08.2013

Менять их — дурной тон, и это делает всевозможные предположения о поведении во время выполнения — гораздо лучше использовать функции времени выполнения, хотя они не предоставляют вам механизма для прямого изменения класса.

person olliej    schedule 18.02.2009

Этот ответ Джошуа Вайнберга дает правильный способ сделать это. Это сработало для меня. :)

И Даррон был прав со своим обоснованным предположением :) это будет работать, только если это суперкласс текущего объекта, и если вы не добавляете никаких членов.

person Alex Zak    schedule 08.01.2012