Значение @property (только для чтения) void * data;в объективе с - PullRequest
0 голосов
/ 24 мая 2019

Я новичок в программировании на iOS, я предпочитаю язык Swift и не знаю Objective C. Хотя я бродил по какой-то библиотеке, я получил значение типа UnsafeMutableRawPointer в swift, которое на самом деле является значением Stringс кодировкой utf8.

Итак, я только что посмотрел на соответствующий целевой класс c, и переменная объявлена ​​как @property (readonly) void *data;

Так почему существует указатель void и почему он преобразуется в UnsafeMutableRawPointer?

Считайте меня нубом в Objective c или c.

Заранее спасибо

1 Ответ

2 голосов
/ 24 мая 2019

Все это может быть довольно много для начинающего, чтобы понять. Итак, начнем с синтаксиса 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 очень небезопасны, когда речь идет о типах данных. Вы можете конвертировать что угодно во что угодно, и вы скомпилируете. Проблема в том, что произойдет во время выполнения.

При взгляде на Свифта все становится намного безопаснее, и вы не можете просто сказать что-то вроде let integer: Int = myDataClass as Int. Вы можете принудительно разыграть его, и он рухнет. Или вы можете сделать дополнительный бросок, и он вернет nil.

Так что после перехода из C / ObjectiveC вы получите небезопасный изменяемый необработанный указатель. Это означает, что он получил место в памяти, не имея представления о том, что это такое и как его использовать. Вы можете попытаться преобразовать его во что угодно, но это небезопасно , поскольку оно игнорирует все проверки типов. Это изменяемый , вероятно, потому что данные, которые он содержит, могут быть изменены в любой момент времени любой системой. Это raw , так как он не содержит никакой дополнительной информации (как будто это строка). И это указатель , потому что он указывает только на позицию в памяти.

(Все фрагменты являются символическими для объяснения того, что происходит под капотом. Пожалуйста, не воспринимайте их буквально)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...