为什么objc_msgSend导致EXC_BAD_ACCESS? [英] Why is objc_msgSend causing an EXC_BAD_ACCESS?

查看:136
本文介绍了为什么objc_msgSend导致EXC_BAD_ACCESS?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个类,给定一个object目标,一个要监视的selector和一个displayTitle将输出以下格式的字符串:@"displayTitle: object.selector".然后,它通过KVO注册自己,这样,只要object.selectorvalue更改,它就可以通知视图控制器更新视图.我将其用作一种抽象且可重用的方式来向用户显示对象的各种属性的描述.

I'm making a class, that given an object target, a selector to watch for, and a displayTitle will output a string in this format: @"displayTitle: object.selector". It then registers itself through KVO so that anytime the value of object.selector changes, it can notify a view controller to update the view. I am using this as an abstract and reusable way to show a description of various properties of an object to a user.

当我尝试获取object.selector的值时,我无法执行[object performSelector:selector],因为此答案所建议的:我使用了objc_msgSend(object, selector).

When I try to get the value of object.selector, I can't do [object performSelector:selector] because LLVM gives errors when you use performSelector with a dynamic selector. So, I did exactly what this answer suggested: I used objc_msgSend(object, selector).

- (instancetype)initWithSelector:(SEL)selector onObject:(NSObject*)object displayTitle:(NSString*)displayTitle {
    self = [super init];

    if (self) {
        id value;

        if ([object respondsToSelector:selector) {
            // Used objc_msgSend instead of performSelector to suppress a LLVM warning which was caused by using a dynamic selector.
            value = objc_msgSend(object, selector);
        } else {
            return nil;
        }

        [self setItemDescription:[NSString stringWithFormat:@"%@: %@", displayTitle, value]];
    }

    return self;
}

我得到了EXC_BAD_ACCESS

如您在屏幕截图中所见,我确保 做[object selector]的作品.

As you can see in the screenshot, I made sure that doing [object selector] works.

这是怎么回事,我该如何解决?

What is going on, and how can I fix it?

推荐答案

您将objc_msgSend调用的结果分配给类型为id的变量,以便ARC启动并尝试保留结果对象(崩溃发生在objc_retain,如您在左侧堆栈中所见).但是,结果不是对象,而是值8的整数,objc_retain被当作指针.但是没有如此低的有效指针,所以您得到了EXC_BAD_ACCESS.

You assign the result of your objc_msgSend call to a variable of type id so ARC kicks in and tries to retain the resulting object (crash is in objc_retain as you can see in the stack to the left). However, the result isn’t an object but an integer of value 8, which objc_retain takes to be a pointer. But there are no valid pointers this low, so you get the EXC_BAD_ACCESS.

只需将value的类型更改为NSUInteger(或任何其他非对象类型).但是,请确保所有潜在的selector返回相同类型的数据.另外,请确保始终返回可以由ARC保留的对象(或nil).

Just change the type of value to be NSUInteger (or any other non-object type). But make sure all potential selectors return data of the same type. Alternatively, make sure to always return an object (or nil), which can be retained by ARC.

这篇关于为什么objc_msgSend导致EXC_BAD_ACCESS?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆