使用CGPoint的object_setInstanceVariable [英] object_setInstanceVariable with CGPoint

查看:106
本文介绍了使用CGPoint的object_setInstanceVariable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人知道如何使用object_setInstanceVariable设置struct变量?它适用于引用类型:

Does anyone know how to set struct variables using object_setInstanceVariable? It is work fine for reference types:

object_setInstanceVariable(obj, "_variable", ref);

但不适用于CGPoint等结构。尝试以下方式:

But do not work for structs such as CGPoint. Tried following ways:

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

我不确定我理解我在做什么(尤其是最后一步)... 。

I'm not sure I understand what I'm doing (especially for the last step)...

提前谢谢你!!!

推荐答案

object_setInstanceVariable object_getInstanceVariable 实际上应该仅用于对象(尽管接口声明似乎另有说明)。你不应该将它们用于内置函数。

object_setInstanceVariable and object_getInstanceVariable are really supposed to be used for objects only (though the interface declaration seems to indicate otherwise). You should not use those for builtins.

更合适的方法是使用 class_getInstanceVariable ivar_getOffset

The more appropriate approach is to use class_getInstanceVariable and 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 *

That cast up there basically turns the object pointer into a pointer to a byte, so it can be added to the offset (which gives us the pointer to the iVar). We have to go through a void* first, because ARC does not allow a direct cast to uint8_t*.

因此可以证明它的使用......

It's use can be demonstrated thusly...

@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 *

Now, you have a way to get the pointer of any iVar... just cast the returned void* appropriately.

BTW,我不建议一般这样做,但是喜欢任何工具,都有运行时函数的用途。

BTW, I don't recommend doing this in general, but like any tool, there are uses for the runtime functions.

糟糕。忘了显示设置值...

Oops. Forgot to show setting the value...

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文件 - 德米特里

I'm sorry, it's still not really clear. Should I get this type (CGRect*) and then pass it to object_setInstanceVariable? Also, I have an error "Undefined symbols "_getIvarPointer"" - please let me know what H file should I include – Dmitry

没有。你根本不应该使用 object_setInstanceVariable 。它应该仅用于作为对象的实例变量。你的是一个CGRect,所以你根本不应该使用那个函数。

No. You should not use object_setInstanceVariable at all. It's supposed to be used only for instance variables that are objects. Yours is a CGRect, so you should not use that function at all.

像最后一个例子一样使用它。也许这个更清楚一些(从你的例子中得到)。

Use it like the very last example. Maybe this one is a bit more clear (it takes from your example).

而不是像你提出的问题那样:

Instead of doing something like your question asked:

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 ,以便链接器可以找到它。

Note, that I defined the getIvarPointer function as static which has file-local scope. It is not an apple-supplied function - you have to write it. If you are going to use this in multiple places, you need to remove the static so the linker can find it.

这篇关于使用CGPoint的object_setInstanceVariable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆