Question

Heres's what I've got as to error.

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

So basically I'm trying to understand How NSString works and trying to find a way to change the pointer that points to "real (char *) string" which is said to be a constant.

So, I found there is a pointer called isa which points to (__NSCFConstantString *). It led me to think that if I change that pointer then I could change the string.

The code I tried was this:

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

And, the result showing that

Before:

enter image description here

After:

enter image description here

It seems changed but it changed every NSString object that has @"hihi" string.

And then what I did was [st3 class] hoping it will give the isa pointer then I got that error message posted on the top.

Could you anyone explain what's going on and why it behaves like this? And, it there any way to intern (i'm not so sure about the term) like in Java?

Please avoid saying just use "NSMutableString" I'm just trying to figure it out seeing there might be some way to do it.

Was it helpful?

Solution

Just use NSMutableString; mutability is why it exists. ;)

NSString is constant. Not just "wraps a const char *" constant, but "no, really, this thing is immutable and the storage details are entirely opaque to you".

In fact, an __NSCFConstantString isn't even stored on the heap at all; there will be no mallocd chunk of memory you can muck with. Such strings are generated by the compiler and the linker lays them down in a chunk of memory that will be read in at runtime and stored on read-only pages of memory.

But not even the results of [NSString stringWithFormat:@"%d World", 42] will have storage in a chunk of uniquely allocated malloc()d memory just for the string buffer. Most likely (but maybe not -- it is an opaque implementation detail), the mechanism for constructing the formatted string will yield an object whose size will be the minimum instance size for whatever private subclass of NSString (see class clusters) is most appropriate + however many bytes are needed to store the string data itself.

While you could potentially find the actual bytes in memory and muck with them directly, that would be a gross violation of encapsulation and utterly useless in a real program.

Note that the isa you are mucking with is an instance variable of NSObject. It is a pointer to the Class object of the instance. It is not necessarily constant, but you really shouldn't muck with it, either.

For more information on the isa and why you are seeing that particular crash when you stuck an NSString instance into the isa slot, my answer to this question may be helpful (maybe):

objc_msgSend() dispatch table

BTW: Love the question -- while you are going down a path that is completely at odds with OO programming and the Foundation, mucking about with the innards and wildly breaking things is a fantastic way to learn! Don't let the down voters get you...well...down, if they should appear.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top