Ios 对象\带有CGPoint的setInstanceVariable

Ios 对象\带有CGPoint的setInstanceVariable,ios,iphone,iphone-privateapi,Ios,Iphone,Iphone Privateapi,有人知道如何使用object_setInstanceVariable设置结构变量吗?对于参考类型来说,这很好: object_setInstanceVariable(obj, "_variable", ref); 但不适用于CGPoint等结构。尝试了以下方法: 1. object_setInstanceVariable(obj, "_variable", point); 2. object_setInstanceVariable(obj, "_variable", &point);

有人知道如何使用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);
我不确定我是否明白我在做什么(尤其是最后一步)


提前谢谢你

object\u setInstanceVariable
object\u getInstanceVariable
实际上应该仅用于对象(尽管接口声明似乎另有指示)。你不应该把这些用于内置设备

更合适的方法是使用
class\u getInstanceVariable
ivar\u 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\u 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*),然后将其传递给对象_setInstanceVariable?还有,我有 “未定义符号”错误\u getIvarPointer“”-请告诉我 我应该包括哪些H文件–Dmitry

不可以。您根本不应该使用
object\u 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
。它不是苹果提供的函数,你必须编写它。如果要在多个位置使用此选项,则需要删除
静态
,以便链接器可以找到它。

好的,我找到了答案。我看一下自地址和可变地址之间的区别:

NSLog(@"%d",self);
NSLog(@"%d",&variable);
例如,差异是24-然后我编写以下代码:

CGPoint *variable = (int)self + 24;
*variable = myCGPoint;
我甚至无法解释它到底有多脏!!!但它是有效的:)


谢谢你的帮助,乔迪,我对你的回答竖起了大拇指。是的,需要一个非常奇怪的字体。对不起,还不太清楚。我是否应该获取此类型(CGRect*),然后将其传递给object_setInstanceVariable?另外,我有一个错误“Undefined symbols”\u getIvarPointer”“-请让我知道我应该包含什么H文件。哦,现在很清楚了,实际上您的选择更好。thanks@Jody哈金斯:这太好了+1.我理解您提到的
object\u getInstanceVariable
class\u getInstanceVariable
的不同用法。但是Obj-C中的类不就是对象吗?因此,我假设可以互换使用这些方法。@Unheilig是的,类是对象,但您需要了解这些函数是Obj-C运行时支持的一部分。这是一个非常糟糕的想法。此外,如果这就是你正在做的,为什么你甚至需要运行时检查?