Я новичок в программировании под iOS, предпочитаю язык Swift и не знаю Objective C. Пока бродил по какой-то библиотеке, получил значение типа UnsafeMutableRawPointer
в swift, то есть на самом деле значение String с кодировкой utf8.
Итак, я просто посмотрел на соответствующий объектный класс c, и переменная объявлена как
@property (readonly) void *data;
Итак, почему указатель недействителен и почему он преобразуется в UnsafeMutableRawPointer
?
Считай меня нубом в Objective c или c.
заранее спасибо
На самом деле это вопрос новичка
Все это может быть довольно много для понимания новичком. Итак, давайте начнем с синтаксиса ObjectiveC:
Свойство @property (readonly) void *data;
предоставляет интерфейсы, которые говорят, что должен быть метод типа - (void *)data
, что означает метод экземпляра, возвращающий указатель void
. Пустой указатель является указателем на что-либо.
В этом случае ObjectiveC является чем-то вроде чистого C на уровень глубже. Я не буду проверять точное преобразование, но поскольку в C нет методов, все делается с помощью функций или даже указателей на функции. Так что где-то внизу должна быть функция (скажем, имя этого класса MyDataClass
)
void *myDataClass_data(MyDataClass *self) { return self->_data; } // Or whatever the implementation is
Так что ничего интересного под капотом не происходит. Все это просто возвращает позицию в памяти без какой-либо дополнительной информации о том, что там должно быть. Вы как разработчик должны знать и интерпретировать это. Из C (или ObjectiveC) это очень просто. Несколько примеров:
char *aString = (char *)myDataClass.data; // A pure C string. Expected to be null terminated
int *arrayOfIntegers = (int *)myDataClass.data; // An array of integers
int thirdItem = arrayOfIntegers[2];
MyDataClass *nextItem = (MyDataClass *)myDataClass.data; // A pointer to another instance
for(MyDataClass *iterator = myDataClass; iterator != nil; iterator = (MyDataClass *)iterator.data) {}
Я надеюсь, вы получите картину. Дело в том, что C, а затем и ObjectiveC очень небезопасны, когда речь идет о типах данных. Вы можете преобразовать что угодно во что угодно, как хотите, и оно скомпилируется. Проблема в том, что произойдет во время выполнения.
При взгляде на Swift все становится намного безопаснее, и вы не можете просто сказать что-то вроде let integer: Int = myDataClass as Int
. Вы можете принудительно применить его, и он рухнет. Или вы можете сделать дополнительный каст, и он вернет nil
.
Поэтому после перехода с C/ObjectiveC вы получите небезопасный изменяемый необработанный указатель. Это означает, что у него есть позиция в памяти, о которой он понятия не имеет, что это такое и как ее использовать. Вы можете попытаться преобразовать его во что угодно, но это небезопасный, поскольку он будет игнорировать все проверки типов. Вероятно, это изменчивый, потому что содержащиеся в нем данные могут быть изменены в любой момент любой системой. Это сырой, поскольку он не содержит дополнительной информации (например, это строка). И это указатель, потому что он указывает только на позицию в памяти.
(Все фрагменты символичны, чтобы объяснить, что происходит под капотом. Пожалуйста, не воспринимайте их буквально)
Я не понимаю вопроса. Почему указатель на void? А почему бы не? Что еще должно быть там?