object_setInstanceVariable с CGPoint

Кто-нибудь знает, как установить структурные переменные, используя object_setInstanceVariable? Это нормально для ссылочных типов:

object_setInstanceVariable(obj, "_variable", ref); 

Но не работайте для таких структур, как CGPoint. Пробовал следующие способы:

 1. object_setInstanceVariable(obj, "_variable", point); 2. object_setInstanceVariable(obj, "_variable", &point); 3. object_setInstanceVariable(obj, "_variable", (void **)&point); 

Я не уверен, что понимаю, что я делаю (особенно для последнего шага) …

Спасибо вам заранее!

2 Solutions collect form web for “object_setInstanceVariable с CGPoint”

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

Более подходящий подход – использовать class_getInstanceVariable и ivar_getOffset .

Например…

 static void* getIvarPointer(id object, char const *name) { Ivar ivar = class_getInstanceVariable(object_getClass(object), name); if (!ivar) return 0; return (uint8_t*)(__bridge void*)object + ivar_getOffset(ivar); } 

То, что брошено там, в основном превращает указатель объекта в указатель на байт, поэтому его можно добавить к смещению (что дает нам указатель на iVar). Сначала нам нужно пройти через void* , потому что ARC не разрешает прямой uint8_t* для uint8_t* .

Это использование может быть продемонстрировано таким образом …

 @implementation Foo { CGRect _rect; } - (CGRect*)rectPointer { CGRect *ptr = getIvarPointer(self, "_rect"); NSAssert(ptr == &_rect, @"runtime discovered pointer should be same as iVar pointer"); return ptr; } 

Теперь у вас есть способ получить указатель на любой iVar … просто верните возвращенную void* соответствующим образом.

Кстати, я не рекомендую делать это вообще, но, как и любой инструмент, есть функции для выполнения функций времени исполнения.

К сожалению. Забыл показать настройку значения …

 CGRect *rectPtr = getIvarPointer(someObject, "_rect"); if (rectPtr) { *rectPtr = CGRectMake(1, 2, 3, 4); } else { // Handle error that the ivar does not exist... } 

РЕДАКТИРОВАТЬ

Извините, это все еще не совсем ясно. Должен ли я получить этот тип (CGRect *), а затем передать его object_setInstanceVariable? Кроме того, у меня есть ошибка «Неопределенные символы» _getIvarPointer »« – пожалуйста, дайте мне знать, какой файл H следует включить – Dmitry

Нет. Вы не должны использовать object_setInstanceVariable вообще. Предполагается, что он используется только для переменных, являющихся объектами. Ваш – CGRect, поэтому вы не должны использовать эту функцию вообще.

Используйте его, как последний пример. Возможно, это немного более ясно (это берет из вашего примера).

Вместо того, чтобы делать что-то вроде вашего вопроса:

 object_setInstanceVariable(obj, "_variable", point); 

Сделай это…

 // Get a pointer to the instance variable. Returns NULL if not found. CGPoint *pointPtr = getIvarPointer(obj, "_variable"); if (pointPtr) { // Now, assign to the point, by de-referencing the pointer. *pointPtr = point; } 

Обратите внимание, что я определил функцию getIvarPointer как static которая имеет локальную область. Это не функция, поставляемая яблоком – вы должны ее написать. Если вы собираетесь использовать это в нескольких местах, вам нужно удалить static чтобы компоновщик мог его найти.

хорошо, я нашел ответ. Я смотрю разницу между адресом SELF и адресом переменной:

 NSLog(@"%d",self); NSLog(@"%d",&variable); 

Например разница равна 24 – тогда я пишу следующий код:

 CGPoint *variable = (int)self + 24; *variable = myCGPoint; 

Я даже не могу объяснить, насколько это грязный хак !!! Но это работает 🙂

Спасибо за помощь Джоди, я сделал большой палец на вас.

  • определять возможность включения горячей точки в iOS с помощью private api's
  • Доступ к частной функции UIKit без использования заголовка моста
  • iOS Enterprise Developer Program: как Apple скажет случайным клиентам от сотрудников?
  • Список доступа к процессам на iOS 9
  • iOS-событие / уведомление о сетевой активности вверх / вниз / выключено
  • Получите CellID, LAC, ... на iOS 8.3
  • Захват CFNotificationCenter для всех уведомлений darwin - iOS
  • Интенсивность пользовательской вибрации iPhone
  • Способ перезагрузки устройства iOS или перезапуск Springboard с использованием частного API?
  • С GSCopyPurpleNamedPort (appId) в GraphicsServices, устаревшим в IOS7, каков альтернативный подход?
  • iOS: не удается заставить BluetoothManager работать
  • PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.