-->

object_setInstanceVariable与CGPoint(object_setInsta

2019-06-27 19:03发布

有谁知道如何使用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);

我不知道我知道我在做什么(尤其是最后一步)...

感谢你提前!

Answer 1:

object_setInstanceVariableobject_getInstanceVariable真的应该只用于对象(虽然接口声明似乎另有指示)。 你不应该使用那些内置命令。

比较合适的方法是使用class_getInstanceVariableivar_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);
}

这投在那里基本上变成对象指针变成一个指向字节,因此它可以被添加到偏移(这给我们的指针伊瓦尔)。 我们通过去void*第一,因为ARC不允许直接投给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;
}

现在,你有办法得到任何伊娃的指针......只投返回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文件 - 梅德

不可以。你不应该使用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因此链接可以找到它。



Answer 2:

好吧,我找到了答案。 我看自身地址和变量地址之间的区别:

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

例如不同的是24 - 然后我写下面的代码:

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

我甚至无法解释它是多少肮脏的黑客! 但是,它的工作原理:)

感谢您的帮助乔迪,我做了一个大拇指在你的答案



文章来源: object_setInstanceVariable with CGPoint