objective-c - 为什么此代码会给出 EXC_BAD_ACCESS(使用 IMP)

标签 objective-c objective-c++ objective-c-runtime

这段代码给我 EXC_BAD_ACCESS,为什么?

NSMutableDictionary  *d = [[NSMutableDictionary alloc] init];
IMP imp= [d methodForSelector:@selector(setObject:forKey:) ];
imp(d,  @selector( setObject:forKey:), @"obj", @"key");

我刚开始使用 IMP,请先尝试.. 运气不好。也不知道为什么我会收到错误消息。在过去,当我收到 EXC_BAD_ACCESS 时,消息会打印在控制台上,这次错误行被突出显示。

一些注意事项: ARC已启用,XCode 4.3.2,项目使用Objective-C++作为默认语言/编译器,这段代码在项目的最开始

谢谢大家

最佳答案

您需要正确转换函数指针,否则 ARC 不知道它应该做什么。 IMP 是一个通用函数指针,它接受一个 id、一个选择器和可变数量的其他未定义参数并返回一个 id。您尝试调用的方法实现采用一个 id,一个选择器后跟恰好两个 id 参数,并具有 void 返回类型。您可以通过更改为以下代码来修复它:

NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
void (*imp)(id, SEL, id, id) = (void(*)(id,SEL,id,id))[dict methodForSelector:@selector(setObject:forKey:)];
if( imp ) imp(dict, @selector(setObject:forKey:), @"obj", @"key");

在取消引用函数指针之前,您应该始终检查是否确实返回了一个函数指针,因为那样也会崩溃。上面的代码甚至可以在 ARC 环境中运行。此外,即使您不使用 ARC,您也应该始终将函数指针转换为实际原型(prototype)而不是 IMP。你不应该使用 IMP。其他会导致主要问题的地方是方法是否返回结构或方法是否采用浮点参数等。

好习惯:如果发现函数指针语法不和谐,请始终强制转换函数指针或为它们创建 typedef。

关于objective-c - 为什么此代码会给出 EXC_BAD_ACCESS(使用 IMP),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10952996/

相关文章:

ios - 自定义字体不显示

opencv - 使用 OpenCV 在 Objective-C++ 中播种和霍夫圆

objective-c - pod 内的供应商框架无法被项目或其他 pod 识别(Cocoapods/Cocoapods #3810)

objective-c - 什么是alt handler,说说Objective-C运行时系统异常处理?

cocoa - Cocoa 中的 @dynamic 属性访问器

ios - 在 Objective-C 中将自定义类注入(inject)子类继承树

iphone - 如何用不同的变量重复一个 Action ?

objective-c - 写入 XCode 构建脚本

iphone - iOS 中的委托(delegate)

ios - 如何使用FTP直接从iOS将图像上传到服务器目录