Подтвердить что ты не робот

Ошибка при использовании "setValue: forKey:" на указателе NSString isa, затем вызывая [string class]

Вот что я имею в виду.

libobjc.A.dylib`_objc_trap():
0x14c13f4:  pushl  %ebp
0x14c13f5:  movl   %esp, %ebp
0x14c13f7:  ud2    

Итак, в основном я пытаюсь понять, как работает NSString и пытается найти способ изменить указатель, который указывает на "настоящую (char *) строку", которая называется константой.

Итак, я обнаружил, что есть указатель isa, который указывает на (__NSCFConstantString *). Это заставило меня подумать, что если я изменю этот указатель, тогда я смогу изменить строку.

Код, который я пробовал, был следующим:

NSString *st3 = [[NSString alloc] initWithString:@"hihi"];
[st3 setValue:@"change" forKey:@"isa"];

И результат, показывающий, что

До:

enter image description here

После того, как:

enter image description here

Кажется измененным, но он изменил каждый NSString объект с строкой @ "hihi".

И тогда то, что я сделал, было [st3 class], надеясь, что оно даст указатель isa, после чего я получил сообщение об ошибке, размещенное вверху.

Не могли бы вы объяснить, что происходит и почему оно ведет себя так? И, это там какой-нибудь способ стажера (я не уверен в этом термине), как в Java?

Пожалуйста, не говорите, просто используйте "NSMutableString". Я просто пытаюсь понять это, видя, что может быть какой-то способ сделать это.

4b9b3361

Ответ 1

Просто используйте NSMutableString; почему она существует.;)

NSString постоянна. Не просто "обертывает константу const char *", но "нет, действительно, эта вещь неизменна, и детали хранилища полностью непрозрачны для вас".

Фактически, __NSCFConstantString вообще не хранится в куче; не будет malloc d фрагмента памяти, с которым вы можете обмануть. Такие строки генерируются компилятором, а компоновщик кладет их в кусок памяти, который будет считываться во время выполнения и храниться на страницах только для чтения.

Но даже результаты [NSString stringWithFormat:@"%d World", 42] не будут храниться в блоке уникально выделенной памяти malloc() d только для строкового буфера. Скорее всего (но, возможно, нет - это непрозрачная деталь реализации), механизм построения форматированной строки даст объект, размер которого будет минимальным размером экземпляра для любого частного подкласса NSString (см. Кластеры классов), наиболее Соответственно +, однако, для хранения самих данных строки требуется много байтов.

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

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

Для получения дополнительной информации о isa и о том, почему вы видите этот конкретный сбой, когда вы вставляете экземпляр NSString в слот isa, мой ответ на этот вопрос может быть полезным (возможно):

таблица отправки objc_msgSend()

BTW: Полюбите вопрос - пока вы идете по пути, который полностью противоречит программированию OO и Фонду, обманывать внутренности и дико взломать вещи - это фантастический способ узнать! Не позволяйте нисходящим избирателям получить вас... ну... вниз, если они появятся.