ios - object_setInstanceVariable 与 CGPoint

标签 ios iphone iphone-privateapi

有谁知道如何使用 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_setInstanceVariableobject_getInstanceVariable 实际上应该只用于对象(尽管接口(interface)声明似乎另有说明)。您不应该将它们用于内置函数。

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

上面的转换基本上将对象指针变成了指向字节的指针,因此它可以添加到偏移量(它为我们提供了指向 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;
}

现在,您有办法获取任何 iVar 的指针...只需适本地转换返回的 void*

顺便说一句,我一般不建议这样做,但与任何工具一样,运行时功能也有用途。

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

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

编辑

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,所以你根本不应该使用那个函数。

像最后一个例子一样使用它。也许这个更清楚一点(它取自您的示例)。

而不是做你问的问题:

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。它不是 apple 提供的函数——您必须自己编写。如果你打算在多个地方使用它,你需要删除 static 以便链接器可以找到它。

关于ios - object_setInstanceVariable 与 CGPoint,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12265083/

相关文章:

ios - UIImage.pngData(_ :) losing Camera photo orientation

ios - Apple 推送通知折叠键等效项

iphone - 我需要释放手势识别器吗?

ios - 通过 BeeTee 应用程序连接到其他蓝牙设备

ios - 通过私有(private) API 获取 UDID

iphone - 核心数据错误?

iphone - 当成功 block 启动时,__block 弱崩溃

iphone - 如何将 -mthumb 添加到 Xcode

iPhone - 为 Interface Builder 创建自定义对象?

ios - 在 iOS 8.3 中获取 CellID、MCC、MNC、LAC、信号强度、质量和网络