object_getIvar读取BOOL iVar值失败



object_getIvar(id object, Ivar Ivar)正确读取Ivar的值,但在BOOL类型的Ivar上失败并崩溃。我需要一个类的所有变量的值。有办法解决吗?

直接访问变量可以使用ARC来完成。你可以访问基本的C类型(char, short, int等)和Objective-C对象。例如,可以使用以下模式访问unsigned char ivar。用其他基本类型替换类型名会产生该类型的ivar的访问器。

unsigned char val;
val = ((unsigned char (*)(id, Ivar))object_getIvar)(object, ivar);
NSLog(@"Looks like I got: %u (or character %c)", val, val);

在幕后,您使用了一些诡计来使编译器认为object_getIvar()实际上是一个返回您所追求的类型的函数。这种类型强制转换改变了编译器调用和解释object_getIvar结果的方式,并且是必需的,因为基本的C类型可以是8到64位大,并且只有编译器知道它们在用作返回值时是如何处理的,这是由您正在编译的体系结构使用的ABI定义的。

是的,它看起来很有趣,但这是最便携的方法,而且,它就是有效的。:-)使用直接类型转换是行不通的,ARC也不允许你这样做。

如果ivar是一个从NSObject派生的对象,你可以直接使用返回值,或者将其类型转换为你期望的对象,没有任何问题,ARC或不ARC

答案有点老了。对于ARC和结构体(或者在访问任何非对象iVar时为了安全起见),您应该这样做:

ptrdiff_t offset = ivar_getOffset(ivar);
unsigned char *stuffBytes = (unsigned char *)(__bridge void *)object;
CGRect gilligans = * ((CGRect *)(stuffBytes + offset));

至少这是让它为我工作的唯一方法。

摘自本页:http://www.bignerdranch.com/blog/inside-the-bracket-part-5-runtime-api/

object_getIvar似乎返回实际值(而不是id),这与手册所说的相反。如果你正在使用ARC,这将导致在试图保留返回值(不是对象)时立即发生处理器故障。

object_getinstancevvariable()返回一个指向信息的指针,但是ARC拒绝接受这个函数

我知道现在评论有点晚了:)但是我面临同样的问题,所有的方法都有不同的问题。ivar_getOffset至少没有传递地址消毒程序。但是KVC的一切都很好。所以,而不是使用指针,只需使用[object setValue: value forKey: key],其中value是您包装的值(使用@(value)为普通/基本值),key是您的ivar的名称。

最新更新