Хранить идентификаторы в массиве C

#ios #objective-c #arrays

#iOS #objective-c #массивы

Вопрос:

Я хотел бы создать массив C, в котором хранятся некоторые объекты, но хотел бы объявить его следующим образом:

 id array = malloc(sizeof(NSObject * 4));
  

Но это выдает ошибку; он просит меня либо:

Исправьте это — используйте __bridge для прямого преобразования (без смены владельца).

Или:

Исправьте это: используйте CFBridgeRelease для вызова передачи права собственности на 1 ‘void’ в ARC.

Я пробовал оба, но все равно выдает ошибку:

Отсутствует)

Я помню, что делал это; но я забыл, как, поскольку прошло некоторое время.

Как я могу сохранить id идентификаторы в массиве C и извлекать из него данные, а затем отбрасывать их?

Комментарии:

1. Какой тип id ? void* , NSObject* или что-то еще?

2. id это просто Objective-C id .

3. @Deduplicator id определяется как указатель на любой объект ObjC.

4. Что не так с предложением Xcode по исправлению? id thing = (__bridge id)(malloc(sizeof(NSObject*)));

5. @EdgarAroutiounian Ошибка, как написано выше «Отсутствует)». Вопрос: id является ли указатель на struct, который указывает на любой Objective-C, поэтому, когда я объявляю массив C, нужно ли мне «уважать» его, чтобы выделить правильную сумму? Потому что все указатели имеют одинаковый размер?

Ответ №1:

Размер указателя одинаков для всех типов, включая объекты, поэтому все, что вам нужно, — это следующее:

 id *myArray = malloc(sizeof(void *) * 4);
  

Обратите внимание, что тип, используемый слева в опубликованном примере, также был неправильным, поскольку ожидается, что на выделяемую память будут ссылаться как на массив указателей C на объекты, а не просто на объект.

Если вы компилируете с включенным ARC, вам нужно будет добавить к объявлению myArray квалификатор срока службы и привести возвращаемое значение malloc . Это потому, что ARC может управлять временем жизни только указателей на объекты, а массив, в котором вы собираетесь хранить объекты, относится к типу C. Например, чтобы явно сообщить ARC, что указатели в массиве неуправляемые, вы могли бы изменить предыдущий код следующим образом:

     __unsafe_unretained id *myArray = (__unsafe_unretained id *) malloc(sizeof(void *) * 4);
  

Обратите внимание, что, поскольку ARC не может управлять количеством сохранений в массивах C, вам предстоит убедиться, что все, что вы храните в массиве, можно безопасно использовать.

Комментарии:

1. Спасибо, но я получаю эту ошибку, используя решение выше: неявное преобразование типа указателя Objective-C ‘void *’ в `__strong id *’ с помощью ARC запрещено .

2. Кажется, это работает. Но мне очень любопытно вот что: правда ли, что мы никогда не должны приводить возвращаемое значение malloc ради хорошей практики-sake и не могли бы вы, пожалуйста, сказать мне, будет ли это нарушать хорошую практику — (__unsafe_unretained id *) ? Заранее спасибо.

3. Теперь я вспомнил, что я также хотел спросить: означает ли это, что в приведенном выше решении это void * то же самое, что id * ? Но я думал, что id сам по себе уже является указателем. Это id* означало бы, что это объявлено как указатель на указатель на id ?

4. void * означает указатель на что-то неопределенного типа, тогда как id означает указатель на объект. id * означает указатель на указатель типа id . id является typedef для struct objc_object * , поэтому typedef включает в себя * .

5. @Unheilig Вы спросили: «Правда ли, что мы никогда не должны приводить возвращаемое значение malloc ради хорошей практики». Где вы это услышали? В некоторых случаях приведение было бы ненужным и, следовательно, просто добавило бы бессмысленный беспорядок в код, но в данном случае это необходимо для того, чтобы предоставить компилятору ARC достаточную информацию о типе, чтобы сделать возможной компиляцию кода.

Ответ №2:

Вы не можете хранить массивы объектов в Objective-C. Это позволяет выделять указатели только на объекты. Для этого правильный синтаксис был бы таким:

 id *array = malloc(sizeof(*array) * 4);
  

или, возможно

 id *array = malloc(sizeof(id) * 4);
  

но первый вариант более СУХОЙ.

Комментарии:

1. Спасибо, но обе версии выдают ошибку: указатель на ‘id’ неконстантного типа без явного владельца .