object_getIvar 无法读取 BOOL iVar 的值

发布于 2024-12-19 13:32:57 字数 129 浏览 2 评论 0原文

object_getIvar(id object, Ivar ivar) 正确读取 iVArs 的值,但在 BOOL 类型 iVar 上失败并崩溃。 我需要一个类的所有 iVar 的值。有什么办法可以解决它吗?

object_getIvar(id object, Ivar ivar) reads the values of iVArs properly but fails on a BOOL type iVar and crashes.
I need the values of all iVars of a class.Is there any way to resolve it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风为裳 2024-12-26 13:32:58

答案有点旧了。使用 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/

The answers are a bit old. With ARC and structs (or to be safe when accessing any non-object iVar), you should do it like this instead:

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

At least this was the only way to get it working for me.

Taken from this page: http://www.bignerdranch.com/blog/inside-the-bracket-part-5-runtime-api/

迟月 2024-12-26 13:32:58

object_getIvar 似乎返回实际值(而不是 id),这与手册所说的相反。如果您使用 ARC,这将在尝试保留非对象的返回值时立即导致处理器错误。

object_getInstanceVariable() 返回指向该信息的指针,但 ARC 拒绝接受该函数。

object_getIvar seems to return the actual value (not an id) which is in opposition to what the manual says. If you are using ARC, this will cause an immediate processor fault during attempt to retain the returned value which is not an object.

object_getInstanceVariable() returns a pointer to the information, but ARC refuses to accept the function.

谎言月老 2024-12-26 13:32:58

我知道现在发表评论有点太晚了:)但我面临着同样的问题,并且所有方法都有不同的问题。 ivar_getOffset 至少不会传递地址清理程序。但一切都可以与 KVC 配合使用。因此,不要使用指针,只需使用 [object setValue: value forKey: key],其中 value 是您的包装值(使用 @(value) 表示普通/基本值),key 是您的 ivar 的名称。

I know it's a bit too late to comment :) But I faced the same issue and all the approaches had different problems. ivar_getOffset doesn't pass the address sanitizer at least. But everything works with KVC. So, instead of using the pointers, just use [object setValue: value forKey: key], where value is your wrapped value (use @(value) for plain/fundamental values) and key is the name of your ivar.

溇涏 2024-12-26 13:32:57

可以使用 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,都不会出现问题。

Accessing ivars directly can be done using ARC. You can access both basic C types (char, short, int, etc.) and Objective-C objects. For example, an unsigned char ivar can be accessed using the following pattern. Replacing the type name with other basic types yields an accessor for that type of ivar.

unsigned char val;

val = ((unsigned char (*)(id, Ivar))object_getIvar)(object, ivar);

NSLog(@"Looks like I got: %u (or character %c)", val, val);

Behind the scenes, you're employing some shenanigans to fake the compiler into thinking that object_getIvar() is actually a function returning the type you are after. This kind of type cast changes the way the compiler calls and interprets the result of object_getIvar, and is required because the basic C types can be 8 to 64 bits big, and only the compiler knows how they're handled when used as return values, which is defined by the ABI used by the architecture you are compiling for.

Yes it looks funny, but it's the most portable way to do it, and, well, it just works. :-) Using a straight type cast will not work, nor will ARC allow you to do it.

If the ivar is an object derived from NSObject, you can use the return value directly, or type cast it to the object you're expecting without issues, ARC or no ARC.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文