Ios in the development process, sometimes use third-party static libraries (.a files), and then import the discovery after compiling normal but there will be run-time selector not recognized
errors, leading app flash back. Then read the documentation library file, you may find that in the document, such as the Other Linker Flags
addition of the -ObjC
or -all_load
such a solution.
So, Other Linker Flags
in the end it is used to doing it? There -ObjC
and -all_load
in the end play what role?
Linker
First, to explain Other Linker Flags
in the end is used to doing. To put it plainly, it is to ld
command other parameters in addition to the default parameters. ld
Command is working to achieve the linker, detailing the terminal can man ld
view.
If someone is not clear what the link is, I can make a simple explanation.
A program from a simple-to-read code into executable files often have to go through the following steps:
Source> Preprocessor> Compiler> Assembler> Encoding> Linker> executables
After the source file after a series of processing, it will generate the corresponding .obj
file, then a project is bound to have a lot of .obj
files, and there will be links between these various documents, such as function calls. Linker to do is to put some of these object files and link libraries used together to form a complete executable file.
I could describe quite superficial, because they know I is not very deep, suggest that you read this article, the linker can do to have a rough idea: linker did
Why would flash back
Apple's official Q & there are so many words on A:
The "selector not recognized" runtime exception occurs due to an issue between the implementation of standard UNIX static libraries, the linker and the dynamic nature of Objective-C. Objective-C does not define linker symbols for each function (or method, in Objective-C) - instead, linker symbols are only generated for each class. If you extend a pre-existing class with categories, the linker does not know to associate the object code of the core class implementation and the category implementation. This prevents objects created in the resulting application from responding to a selector that is defined in the category.
Translated, it probably means that Objective-C
the linker does not create the symbol table for each method, but only for the establishment of a class symbol table. In this case, if the static library defines the classification of a class that already exists, the linker will think this class already exists, not the classification code and core classes together. In this case, in the final executable file, it will lack in the classification code, so the function call failed.
Solution
Solutions in the context of the piece I mentioned, that is, Other Linker Flags
in adding the required parameters, the parameters used generally have the following three:
-ObjC
-all_load
-force_load
The following is the meaning of existence says each parameter and do specific things.
First -ObjC
, the general this parameter is sufficient to solve the problems mentioned above, Apple's official description is as follows:
This flag causes the linker to load every object file in the library that defines an Objective-C class or category. While this option will typically result in a larger executable (due to additional object code loaded into the application), it will allow the successful creation of effective Objective-C static libraries that contain categories on existing classes.
Simply put, the addition of this argument, the linker will put all the static library Objective-C
classes and classification are loaded into the final executable files, although this may be because a lot of unnecessary files to load caused by an executable file larger, but this parameter is a good solution to the problems we encountered. But the fact really is that right?
If the -ObjC
argument really so effective, then things would be much simpler.
Important: For 64-bit and iPhone OS applications, there is a linker bug that prevents -ObjC from loading objects files from static libraries that contain only categories and no classes. The workaround is to use the -allload or -forceload flags.
When a static library, only classification and no class, the -ObjC
parameters will be ineffective. This time, we need to use -all_load
or -force_load
up.
-all_load
The linker will find all the object files are loaded into the executable file, but do not just use this parameter! If you use more than one static library file, and then use this parameter, you will likely encounter ld: duplicate symbol
an error, because different library files which may have the same destination file, it is recommended that in the face of -ObjC
the case of failure use -force_load
parameters.
-force_load
Doing things with -all_load
in fact is the same, but -force_load
need to specify the path to the library file to be loaded all, this is the case, you're just a library file is fully loaded, loaded on demand without affecting the rest of the library file.