object_getIvar(id object,Ivar ivar)正确读取iVArs的值,但在BOOL类型iVar上失败并崩溃。 我需要一个类的所有iVars的值。有什么方法可以解决它。
答案 0 :(得分:22)
使用ARC直接访问ivars 可以。您可以访问基本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。
答案 1 :(得分:5)
答案有点旧。使用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/
答案 2 :(得分:4)
object_getIvar似乎返回实际值(不是id),这与手册所说的相反。如果您使用ARC,则在尝试保留不是对象的返回值时,这将立即导致处理器故障。
object_getInstanceVariable()返回指向信息的指针,但ARC拒绝接受该函数。
答案 3 :(得分:0)
我知道现在评论还为时已晚:)但是我面临着相同的问题,所有方法都存在不同的问题。 ivar_getOffset至少不通过地址清理器。但是一切都可以在KVC中使用。因此,不用使用指针,只需使用[object setValue:value forKey:key],其中value是包装的值(对于普通/基本值使用@(value)),而key是ivar的名称。