Ответ 1
Короткий ответ: эта строка имеет тип NSCFString
, класс, который наследует от NSMutableString
, поэтому он отвечает селекторам для методов, объявленных в NSMutableString
, включая суперклассы.
Не так короткий ответ: Строковые строки беспошлины соединяются с строками Core Foundation. Разработчики используют непрозрачные типы CFStringRef
(привязанные к NSString
) и CFMutableStringRef
(привязанные к NSMutableString
), чтобы ссылаться на эти строки, поэтому на первый взгляд существуют два разных типа строк: неизменяемые и изменяемые.
С точки зрения внутренней реализации Core Foundation, это частный тип, называемый struct __CFString
. Этот частный тип хранит поле бит, которое хранит, помимо прочего, информацию о том, является ли строка изменчивой или неизменяемой. Наличие одного типа упрощает реализацию, поскольку многие функции разделяются как неизменяемыми, так и изменяемыми строками.
Всякий раз, когда вызывается функция Core Foundation, которая работает с изменяемыми строками, она сначала считывает это поле бит и проверяет, является ли строка изменчивой или неизменяемой. Если аргумент должен быть изменчивой строкой, но на самом деле isnt, функция возвращает ошибку (например, _CFStringErrNotMutable
) или не выполняет утверждение (например, __CFAssertIsStringAndMutable(cf)
).
Во всяком случае, это детали реализации, и они могут измениться в будущем. Тот факт, что NSString
не объявляет -appendString:
, не означает, что каждый экземпляр NSString
не отвечает на соответствующий селектор - думаю substitutability. Такая же ситуация применима и к другим изменяемым/неизменяемым классам, таким как NSArray
и NSMutableArray
. С точки зрения разработчика важно то, что возвращаемый объект имеет тип, который соответствует типу возврата - это может быть сам тип или любой подтип этого типа. Кластеры кластера делают это еще более запутанным, но ситуация не ограничивается кластерами классов как таковыми.
Таким образом, вы можете только ожидать, что метод возвращает объект, тип которого принадлежит иерархии (то есть либо самого типа, либо подтипа) для типа возвращаемого значения. К сожалению, это означает, что вы не можете проверить, является ли объект Foundation изменчивым или нет. Но опять же, вам действительно нужна эта проверка?
Вы можете использовать функцию CFShowStr()
для получения информации из строки. В примере в вашем вопросе добавьте
CFShowStr((CFStringRef)myString);
Вы должны получить результат, похожий на:
Length 0
IsEightBit 1
HasLengthByte 0
HasNullByte 1
InlineContents 0
Allocator SystemDefault
Mutable 0
Contents 0x0
где
Mutable 0
означает, что строка фактически неизменяема.