使用64位arm64构建时,obj_msgSend函数指针崩溃

ben*_*nck 5 crash 64-bit objective-c ios7 arm64

实际上我的原始代码适用于Xcode 5.0.2,也非常适合发送到App Store,它是:

objc_msgSend(self.target, self.successAction, category);
Run Code Online (Sandbox Code Playgroud)

此行导致Xcode5.1 beta5崩溃.我找到了修复崩溃的解决方案: SudzC ARC版本 - objc_msgSend调用使用64位架构导致EXC_BAD_ACCESS

// solution
id (*response)(id, SEL, id) = (id (*)(id, SEL, id)) objc_msgSend;
response(self.target, self.successAction, category);
Run Code Online (Sandbox Code Playgroud)

在使用推荐的解决方案时,使用Xcode 5或Xcode5.1beta在设备(iPhone 5s)或模拟器(32位或64位)上进行测试时完全没有问题.构建设置中的体系结构设置是Xcode 5中的"标准体系结构(armv7,armv7s)"和"标准体系结构(armv7,armv7s,arm64)".

但是,我的新版应用程序已于今天在App Store上发售.它会在安装的每台设备(iPhone 5s,5,4s)上崩溃(根据Crashlytics报告).由于我没有使用Xcode(构建到真实设备)获得崩溃,我不知道在Apple审核之前我是否解决了这个问题.

ben*_*nck 9

最后,我现在可以重现崩溃.只需编辑Build Scheme并将"Run YOURAPPNAME.app"从Debug更改为Release.

在我可以重现这个bug之后,我知道如何修复它.由于我的选择器函数类型是void(不返回任何内容),我不应该只复制问题所做的(使用"id").

通过更改:

id (*response)(id, SEL, id) = (id (*)(id, SEL, id)) objc_msgSend;
response(self.target, self.successAction, category);
Run Code Online (Sandbox Code Playgroud)

至:

void (*response)(id, SEL, id) = (void (*)(id, SEL, id)) objc_msgSend;
response(self.target, self.successAction, category);
Run Code Online (Sandbox Code Playgroud)

它修复!! 或者感谢github上的这个提交的单行代码:

((void(*)(id, SEL, id))objc_msgSend)(self.target, self.successAction, category);
Run Code Online (Sandbox Code Playgroud)