How do I fix "selector not recognized" runtime exceptions when trying to use category methods from a static library?
https://developer.apple.com/library/content/qa/qa1490/_index.html
A: If you're seeing a "selector not recognized" runtime exception when calling a category method that is implemented in a static library, you are hitting the link-time build issue described here, and need to add the -ObjC linker flag to your project, by following these steps:
In Xcode, choose View > Navigators > Show Project Navigator, or press
⌘1.Select your project under the PROJECT heading in the Project Navigator, then select the Build Settings tab.
Scroll down to the Other Linker Flags build setting under the Linking collection, or type "Other Linker Flags" into the search bar.
Set the value of the Other Linker Flags build setting to
$(OTHER_LDFLAGS) -ObjC.
Figure 1 Modifying the Other Linker Flags build setting
Troubleshooting
If adding the -ObjC flag isn't fixing the problem, double check that a conflicting Target build setting is not overriding it, by following the above steps, but selecting the current target under "TARGETS" in step 2, instead of the project.
Other Causes of selector not recognized Exceptions
The most common causes of a "selector not recognized" exception are:
No Such Method
The method really does not exist. Check your spelling. Check documentation to verify that the method exists on the version of the operating system your app is using.
Memory Management
Your app is trying to use an object after it has been deallocated, use the Zombies instrument to debug this kind of problem. You are seeing "selector not recognized" because the memory has been re-allocated as a different kind of object.
What causes those exceptions?
An impedance mismatch between UNIX static libraries and the dynamic nature of Objective-C can cause category methods in static libraries to not be linked into an app, resulting in "selector not recognized" exceptions when the methods aren't found at runtime.
The Linker
When a C program is compiled, each "source file" is turned into an "object file" that contains executable functions and static data. The linker glues these object files together into a final executable. That executable is eventually bundled into an app by Xcode.
When a source file uses something (like a function) defined in another file, then an undefined symbol is written into the object file, to "stand in" for the missing thing. The linker resolves these symbols by pulling in the object files that include definitions of undefined symbols when building the final executable.
For example, if main.c uses the function foo(), where foo is defined in another file, B.c, then the object file main.o will have an unresolved symbol for foo(), and B.o will include an implementation of foo(). At link time, B.o will be brought into the final executable, so that the code in main.o now references the implementation of foo() defined in B.o.
A UNIX static library is just a collection of object files. Normally the linker only pulls in an object file from a static library if doing so would resolve some undefined symbol. Not pulling in all object files reduces the size of the final executable.
Objective-C
The dynamic nature of Objective-C complicates things slightly. Because the code that implements a method is not determined until the method is actually called, Objective-C does not define linker symbols for methods. Linker symbols are only defined for classes.
For example, if main.m includes the code [[FooClass alloc] initWithBar:nil]; then main.o will contain an undefined symbol for FooClass, but no linker symbols for the -initWithBar:method will be in main.o.
Since categories are a collection of methods, using a category's method does not generate an undefined symbol. This means the linker does not know to load an object file defining the category, if the class itself is already defined. This causes the same "selector not recognized" runtime exception you would see for any unimplemented method.
The -ObjC Linker Flag
Passing the -ObjC option to the linker causes it to load all members of static libraries that implement any Objective-C class or category. This will pickup any category method implementations. But it can make the resulting executable larger, and may pickup unnecessary objects. For this reason it is not on by default.
How do I fix "selector not recognized" runtime exceptions when trying to use category methods from a static library?的更多相关文章
- Effective Java 58 Use checked exceptions for recoverable conditions and runtime exceptions for programming errors
Three kinds of throwables Throwables Checked Recoverable checked exceptions Y Y runtime exceptions N ...
- iOS的Runtime机制下给类别(category)添加属性、替换原有类的方法执行
一.Runtime的理解 OC是面向对象的语言这是常识,其实就是通过Runtime机制动态创建类和对象,这里只是简单的运用runtime的使用! 二.类别(category)添加属性_使用前记得导入头 ...
- Building Objective-C static libraries with categories
Q: How do I fix "selector not recognized" runtime exceptions when trying to use category m ...
- Other Linker Flags到底是什么
一.问题描述 在项目开发中用到百度地图,有时候在工程中会报“方法找不到”的错误(unrecognized selector sent to instance). 二.问题分析 首先,要说明一下Othe ...
- 【转】关于Xcode的Other Linker Flags
链接器 首先,要说明一下Other Linker Flags到底是用来干嘛的.说白了,就是ld命令除了默认参数外的其他参数.ld命令实现的是链接器的工作,详细说明可以在终端man ld查看. 如果有人 ...
- 关于Xcode的Other Linker Flags
背景 在ios开发过程中,有时候会用到第三方的静态库(.a文件),然后导入后发现编译正常但运行时会出现selector not recognized的错误,从而导致app闪退.接着仔细阅读库文件的说明 ...
- Xcode 编辑器之关于Other Linker Flags相关问题
一,概述 问题场景一 当从网上去下载一些之前的完整的项目的时候,用终端也 pod update了,但一运行,熟悉的linker错误就出来了. 解决办法 在Other Linker Flags(也即 O ...
- Selector
原文: https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Sele ...
- Objective C运行时(runtime)
#import <objc/runtime.h> void setBeingRemoved(id __self, SEL _cmd) { NSLog(@"------------ ...
随机推荐
- [工具]法国神器mimikatz 2.1.1 一键版 & PowerShell版
无需任何参数,运行EXE即可自动读取Windows系统密码 EXE版需要其它功能请使用原版 (参数已写死仅读密码) 结果保存于当前目录mz.log EXE https://github.com/k8g ...
- spring boot 源码解析52-actuate中MVCEndPoint解析
今天有个别项目的jolokia的endpoint不能访问,调试源码发现:endpoint.enabled的开关导致的. 关于Endpoint, <Springboot Endpoint之二:En ...
- ZYNQ笔记(6):普通自定义IP封装实现PL精准定时中断
软件的定时中断很难控制精准触发沿的位置,可以通过 PL-PS 的中断完成精准的定时中断.PL 的中断通过 Verilog 代码产生,这样紧密结合 PS-PL 的处理,发挥各自的优势. 一.PL 侧定时 ...
- kubectl 创建 Pod 背后到底发生了什么?
原文链接:kubectl 创建 Pod 背后到底发生了什么? 想象一下,如果我想将 nginx 部署到 Kubernetes 集群,我可能会在终端中输入类似这样的命令: $ kubectl run - ...
- 【在 Nervos CKB 上做开发】Nervos CKB 脚本编程简介[5]:调试 debug
作者:Xuejie 原文链接:https://xuejie.space/2019_10_18_introduction_to_ckb_script_programming_debugging/ Ner ...
- Java3-5年经验面试题总结
记录一下本次找工作所遇到的一些高频面试题,第一次找java工作,感觉比面试.net舒服多了,17年的时候出去找.net工作,由于在公司做的东西用到的技术少,除了mvc和ef,其他没啥问的,就追着项目问 ...
- 鼠标按下改变RelativeLayout背景颜色,松开变回
在drawable下创建bg.xml文件 <?xml version="1.0" encoding="utf-8"?> <selector x ...
- 编写可维护的JavaScript-随笔(七)
将配置数据从代码中分离出来 代码中有些数据有修改的可能,如果放在函数中的话后期修改的时候会带来一些不必要的风险 需要将配置数据从代码中抽取出来,如果配置数据多的话可以放入一个对象中,然后修改抽取出来的 ...
- FreePascal - Typhon如何添加不能识别单元?
Typhon 32位 6.9 问题:想使用LSUtils单元,这个单元在Lazarus里面,直接引入就可以使用,而且单元头注释明显写明是CodeTyphon工程的一部分,那么正常在Typhon只要引入 ...
- Spring boot应用如何支持https
首先使用命令行生成一个keystore文件: keytool -genkey -alias tomcat -keyalg RSA -keystore ./jerry.keystore 保存到本地项目文 ...