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:

  1. In Xcode, choose View > Navigators > Show Project Navigator, or press ⌘1.

  2. Select your project under the PROJECT heading in the Project Navigator, then select the Build Settings tab.

  3. Scroll down to the Other Linker Flags build setting under the Linking collection, or type "Other Linker Flags" into the search bar.

  4. 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?的更多相关文章

  1. 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 ...

  2. iOS的Runtime机制下给类别(category)添加属性、替换原有类的方法执行

    一.Runtime的理解 OC是面向对象的语言这是常识,其实就是通过Runtime机制动态创建类和对象,这里只是简单的运用runtime的使用! 二.类别(category)添加属性_使用前记得导入头 ...

  3. Building Objective-C static libraries with categories

    Q: How do I fix "selector not recognized" runtime exceptions when trying to use category m ...

  4. Other Linker Flags到底是什么

    一.问题描述 在项目开发中用到百度地图,有时候在工程中会报“方法找不到”的错误(unrecognized selector sent to instance). 二.问题分析 首先,要说明一下Othe ...

  5. 【转】关于Xcode的Other Linker Flags

    链接器 首先,要说明一下Other Linker Flags到底是用来干嘛的.说白了,就是ld命令除了默认参数外的其他参数.ld命令实现的是链接器的工作,详细说明可以在终端man ld查看. 如果有人 ...

  6. 关于Xcode的Other Linker Flags

    背景 在ios开发过程中,有时候会用到第三方的静态库(.a文件),然后导入后发现编译正常但运行时会出现selector not recognized的错误,从而导致app闪退.接着仔细阅读库文件的说明 ...

  7. Xcode 编辑器之关于Other Linker Flags相关问题

    一,概述 问题场景一 当从网上去下载一些之前的完整的项目的时候,用终端也 pod update了,但一运行,熟悉的linker错误就出来了. 解决办法 在Other Linker Flags(也即 O ...

  8. Selector

    原文: https://developer.apple.com/library/ios/documentation/General/Conceptual/DevPedia-CocoaCore/Sele ...

  9. Objective C运行时(runtime)

    #import <objc/runtime.h> void setBeingRemoved(id __self, SEL _cmd) { NSLog(@"------------ ...

随机推荐

  1. Linux 教你如何预防删库到跑路

    学习linux之前,有几个命令是必须记住的 我们最常见的删库命令 rm -rf /** 这个命令可以在你心情不好的时候,对着公司服务器操作一番,保证让你一时爽, 删完库这个时候你就该跑路了,但是你真的 ...

  2. python的JSON库

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写. 1.json库的使用 使用 JSON 函数需要导入 json 库:import jso ...

  3. 9. Scala隐式转换和隐式值

    9.1 隐式转换 9.1.1 提出问题 先看一个案例演示,引出隐式转换的实际需要=>指定某些数据类型的相互转化 object boke_demo01 { def main(args: Array ...

  4. 核与线程 CPU 4核8线程 的解释

    1.物理CPU: 物理CPU就是计算机上实际配置的CPU个数.在linux上可以打开cat /proc/cpuinfo 来查看,其中的physical id就是每个物理CPU的ID,能找到几个phys ...

  5. using 语句(C# 参考)(转载)

    using 语句 提供可确保正确使用 IDisposable对象的方便语法. 示例 下面的示例演示如何使用 using 语句. using (var font1 = new Font("Ar ...

  6. asp.net core 系列之允许跨域访问-1(Enable Cross-Origin Requests:CORS)

    接上篇的允许跨域 4.CORS 策略(Policy)的选项 这里讲解Policy可以设置的选项: 设置允许的访问源 设置允许的HTTP methods 设置允许的请求头(request header) ...

  7. JavaScript入门(一)

    JavaScript入门篇—开篇 Document对象 1Document对象表示当前页面,HTML在浏览器中是以DOM形式表示为树形结构.Document是DOM树的根节点.(因此需要查找DOM树中 ...

  8. 3.Javascript实现instanceof

    instanceof instanceof 用于判断某个对象是否是另一个对象(构造方法)的实例.instanceof会查找原型链,直到null如果还不是后面这个对象的实例的话就返回false,否则就返 ...

  9. MES应用案例 | 天博集团成功完成数字化转型

    受到智能制造观念和技术的巨大且快速的影响,使得工业特别是汽车行业必须以最快速度赶上这场企业数字化转型的浪潮,唯有实现企业转型升级才能在这场速度战中占得先机.当然关于企业的转型升级,最为重要的是需要打造 ...

  10. rabbitmq:配置rabbitmq-management插件

    rabbitmq提供了一个图形的管理界面,用于管理.监控rabbitmq的运行情况,它是以插件的形式提供的,如果要启用需要启用插件 一.启用插件 rabbitmq-plugins enable rab ...