I have some very simple Objective-C code that allocates and initialises an NSString and then gets the UTF-8 const char * representation of that string as follows:
const char *s = [[[NSString alloc] initWithFormat:@"%s", "£"] UTF8String];
I then print out the hex values of the code units that make up this string using this code:
while(*s)
printf("%02x ", (unsigned int) *s++);
and I get the following output:
ffffffc2 ffffffac ffffffc2 ffffffa3
This is unexpected as I'd assume I'd just get ffffffc2 ffffffa3, seeing as the £ character is made up of two code units, represented in hex as c2 followed by a3, as you can see here.
Here's a screenshot of this output in the simplest iOS app imaginable running locally on my laptop:
Note that the output is the same if I create the NSString as follows:
[[NSString alloc] initWithFormat:@"%s", "\xc2\xa3"]
If I instead use an NSString as the argument to be interpolated into the format string then I get the expected output of ffffffc2 ffffffa3:
[[NSString alloc] initWithFormat:@"%@", @"£"]
What's even stranger to me is that exactly the same failing code as I have above (the first version) seems to work as I'd expect when on an online Objective C codepen-type site I found, which you can see here.
Why are the extra code units being added to the UTF-8 representation of the string when I use the initWithFormat:@"%s" version of the code, and seemingly only when I run it on my machine?

NSStringwith[[NSString alloc] initWithUTF8String: str]?"£"?[NSString defaultCStringEncoding]"£"argument ofinitWithFormatMacOSRoman?