在NSString的isa指针上使用"setValue:forKey:"然后调用[string class]时出错

den*_*hoe 19 objective-c objective-c-runtime nsstring

Heres是我得到的错误.

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

所以基本上我试图理解如何NSString工作并试图找到一种方法来改变指向"真(char*)字符串"的指针,这被称为常量.

所以,我发现有一个名为isa的指针指向(__NSCFConstantString *).它让我想到,如果我改变那个指针,那么我可以改变字符串.

我试过的代码是这样的:

NSString *st3 = [[NSString alloc] initWithString:@"hihi"];
[st3 setValue:@"change" forKey:@"isa"];
Run Code Online (Sandbox Code Playgroud)

并且,结果表明

之前:

在此输入图像描述

后:

在此输入图像描述

它似乎改变了,但它改变了每个NSString具有@"hihi"字符串的对象.

然后我做的是[st3 class]希望它会给出isa指针然后我在顶部发布了错误消息.

你能解释一下发生了什么以及为什么会这样吗?而且,有没有办法实习(我不太确定这个术语)就像在Java中一样?

请避免说只使用"NSMutableString"我只是想弄清楚是否可能有某种方法可以做到这一点.

bbu*_*bum 29

只是用NSMutableString; 可变性是它存在的原因.;)

NSString是不变的.不只是"包装const char *"常量,但"不,真的,这个东西是不可变的,存储细节对你来说完全不透明".

事实上,__NSCFConstantString甚至根本没有存储在堆上; 没有malloc你可以捣乱的大块记忆.这些字符串由编译器生成,并且链接器将它们放在一块内存中,该内存块将在运行时读入并存储在只读存储器页面上.

但是,即使结果也[NSString stringWithFormat:@"%d World", 42]不会malloc()仅仅为字符串缓冲区存储在一块唯一分配的内存中. 最有可能(但可能不是 - 它是一个不透明的实现细节),构造格式化字符串的机制将产生一个对象,其大小将是任何私有子类NSString(参见类集群)最合适的最小实例大小+但是存储字符串数据本身需要许多字节.

虽然你可能会在内存中找到实际的字节并直接找到它们,但这将严重违反封装并在实际程序中完全无用.

请注意,isa您正在使用的是一个实例变量NSObject.它是指向实例的Class对象的指针.它不一定是恒定的,但你也不应该捣乱它.

有关isa当您将NSString实例插入isa插槽时看到特定崩溃的原因和原因的更多信息,我对这个问题的回答可能会有所帮助(可能):

objc_msgSend()调度表

顺便说一句:喜欢这个问题 - 当你走上与OO编程和基金会完全不一致的道路时,对内脏进行捣乱并疯狂地破坏事物是一种极好的学习方式!不要让失败的选民得到你......好吧......如果他们应该出现的话.

  • @bbum谢谢你的最后一句话先生,这会帮助我并让我振作起来. (2认同)