Dmi*_*try 3 iphone iphone-privateapi ios
有谁知道如何使用object_setInstanceVariable设置结构变量?它适用于参考类型:
object_setInstanceVariable(obj, "_variable", ref);
Run Code Online (Sandbox Code Playgroud)
但不适用于CGPoint等结构.尝试以下方式:
1. object_setInstanceVariable(obj, "_variable", point);
2. object_setInstanceVariable(obj, "_variable", &point);
3. object_setInstanceVariable(obj, "_variable", (void **)&point);
Run Code Online (Sandbox Code Playgroud)
我不确定我理解我在做什么(尤其是最后一步)......
提前谢谢你!!!
Jod*_*ins 10
object_setInstanceVariable并且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);
}
Run Code Online (Sandbox Code Playgroud)
那里的转换基本上将对象指针转换为指向字节的指针,因此可以将其添加到偏移量(它为我们提供指向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;
}
Run Code Online (Sandbox Code Playgroud)
现在,你有办法获得任何iVar的指针...只需void*适当地投射返回.
顺便说一下,我不建议一般这样做,但是像任何工具一样,运行时函数也有用处.
哎呀.忘了显示设置值...
CGRect *rectPtr = getIvarPointer(someObject, "_rect");
if (rectPtr) {
*rectPtr = CGRectMake(1, 2, 3, 4);
} else {
// Handle error that the ivar does not exist...
}
Run Code Online (Sandbox Code Playgroud)
编辑
对不起,现在还不是很清楚.我应该得到这种类型(CGRect*)然后将它传递给object_setInstanceVariable吗?此外,我有一个错误"未定义的符号"_getIvarPointer"" - 请让我知道我应该包括什么H文件 - 德米特里
不,你根本不应该使用object_setInstanceVariable.它应该仅用于作为对象的实例变量.你的是一个CGRect,所以你根本不应该使用该功能.
像最后一个例子一样使用它.也许这个更清楚一些(从你的例子中得到).
而不是像你的问题那样做:
object_setInstanceVariable(obj, "_variable", point);
Run Code Online (Sandbox Code Playgroud)
做这个...
// 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;
}
Run Code Online (Sandbox Code Playgroud)
注意,我定义了具有文件本地范围的getIvarPointer函数static.它不是苹果提供的功能 - 你必须写它.如果要在多个位置使用它,则需要删除它,static以便链接器可以找到它.