*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Deadpool guns]: unrecognized selector sent to instance 0x7ffecbc12df0'
otool -tV -arch x86_64 libDeadpool.a
Archive : libDeadpool.a libDeadpool.a(Deadpool+Guns.o): (__TEXT,__text) section -[Deadpool(Guns) guns]: 0000000000000000 pushq %rbp 0000000000000001 movq %rsp, %rbp 0000000000000004 subq $0x10, %rsp 0000000000000008 leaq 0x71(%rip), %rax ## Objc cfstring ref: @"sword 2" 000000000000000f movd %rax, %xmm0 0000000000000014 leaq 0x45(%rip), %rax ## Objc cfstring ref: @"sword 1" 000000000000001b movd %rax, %xmm1 0000000000000020 punpcklqdq %xmm0, %xmm1 ## xmm1 = xmm1[0],xmm0[0] 0000000000000024 movdqa %xmm1, -0x10(%rbp) 0000000000000029 movq 0x70(%rip), %rdi ## Objc class ref: NSArray 0000000000000030 movq 0x91(%rip), %rsi ## Objc selector ref: arrayWithObjects:count: 0000000000000037 leaq -0x10(%rbp), %rdx 000000000000003b movl $0x2, %ecx 0000000000000040 callq *_objc_msgSend(%rip) 0000000000000046 addq $0x10, %rsp 000000000000004a popq %rbp 000000000000004b retq libDeadpool.a(Deadpool.o): (__TEXT,__text) section -[Deadpool name]: 0000000000000000 pushq %rbp 0000000000000001 movq %rsp, %rbp 0000000000000004 movq 0x1d(%rip), %rsi ## Objc selector ref: class 000000000000000b callq *_objc_msgSend(%rip) 0000000000000011 movq %rax, %rdi 0000000000000014 popq %rbp 0000000000000015 jmp _NSStringFromClass
otool -tV -arch x86_64 DemoApp.app/DemoApp | grep Deadpool
0000000100001ae8 movq 0x21f1(%rip), %rdi ## Objc class ref: Deadpool 0000000100001af6 movq 0x1513(%rip), %r12 ## Objc message: +[Deadpool new] -[Deadpool name]:
When the C program is compiled, each file (.c) is compiled into a so-called “object file” (.o), which contains implementations of functions and other static information. After the linker collects all these files into one final file - executable. And this executable file just gets inside our .app by means of Xcode.
But when the source file (.c) uses something, for example, a function that is defined in another file (another .c file), then the “undefined symbol” is written to the .o file for this piece of code. And at the assembly stage, the linker has enough information to understand where it is necessary to pull out the missing thing from the “undefined symbol” in order to collect the final executable. This description is for building a UNIX static library.
Due to the dynamic nature of the language, this process in Objective-C is a bit complicated, since the search for the implementation of a method occurs only after the fact that the method is accessed. Objective-C does not define auxiliary symbols for linker methods, but only defines symbols for classes. For example, in the class / main.o file there is a code:
[[FooClass alloc] initWithBar: nil]
that is, FooClass is a separate class, in a separate FooClass.o file, so main.o will only contain an “undefined symbol” for FooClass itself, but no additional symbols for the -initWithBar method: in this class.
Since a category is just a separate file with methods, the linker has absolutely no information that this file needs to be linked, since no methods are created for the linker “undefined symbol”.
Archive : libDeadpool.a libDeadpool.a(Deadpool+Guns.o): (__TEXT,__text) section -[Deadpool(Guns) guns]: 0000000000000000 pushq %rbp 0000000000000001 movq %rsp, %rbp 0000000000000004 subq $0x10, %rsp 0000000000000008 leaq 0x71(%rip), %rax ## Objc cfstring ref: @"sword 2" 000000000000000f movd %rax, %xmm0 0000000000000014 leaq 0x45(%rip), %rax ## Objc cfstring ref: @"sword 1" 000000000000001b movd %rax, %xmm1 0000000000000020 punpcklqdq %xmm0, %xmm1 ## xmm1 = xmm1[0],xmm0[0] 0000000000000024 movdqa %xmm1, -0x10(%rbp) 0000000000000029 movq 0x70(%rip), %rdi ## Objc class ref: NSArray 0000000000000030 movq 0x91(%rip), %rsi ## Objc selector ref: arrayWithObjects:count: 0000000000000037 leaq -0x10(%rbp), %rdx 000000000000003b movl $0x2, %ecx 0000000000000040 callq *_objc_msgSend(%rip) 0000000000000046 addq $0x10, %rsp 000000000000004a popq %rbp 000000000000004b retq libDeadpool.a(Deadpool.o): (__TEXT,__text) section -[Deadpool name]: 0000000000000000 pushq %rbp 0000000000000001 movq %rsp, %rbp 0000000000000004 movq 0x1d(%rip), %rsi ## Objc selector ref: class 000000000000000b callq *_objc_msgSend(%rip) 0000000000000011 movq %rax, %rdi 0000000000000014 popq %rbp 0000000000000015 jmp _NSStringFromClass
otool -tV -arch x86_64 libDeadpool.a
Archive : libDeadpool.a libDeadpool.a(libDeadpool.a-x86_64-master.o): (__TEXT,__text) section -[Deadpool(Guns) guns]: 0000000000000000 pushq %rbp 0000000000000001 movq %rsp, %rbp 0000000000000004 subq $0x10, %rsp 0000000000000008 leaq 0x149(%rip), %rax ## Objc cfstring ref: @"sword 2" 000000000000000f movd %rax, %xmm0 0000000000000014 leaq 0x11d(%rip), %rax ## Objc cfstring ref: @"sword 1" 000000000000001b movd %rax, %xmm1 0000000000000020 punpcklqdq %xmm0, %xmm1 ## xmm1 = xmm1[0],xmm0[0] 0000000000000024 movdqa %xmm1, -0x10(%rbp) 0000000000000029 movq 0x270(%rip), %rdi ## Objc class ref: NSArray 0000000000000030 movq 0x259(%rip), %rsi ## Objc selector ref: arrayWithObjects:count: 0000000000000037 leaq -0x10(%rbp), %rdx 000000000000003b movl $0x2, %ecx 0000000000000040 callq *_objc_msgSend(%rip) 0000000000000046 addq $0x10, %rsp 000000000000004a popq %rbp 000000000000004b retq -[Deadpool name]: 000000000000004c pushq %rbp 000000000000004d movq %rsp, %rbp 0000000000000050 movq 0x241(%rip), %rsi ## Objc selector ref: class 0000000000000057 callq *_objc_msgSend(%rip) 000000000000005d movq %rax, %rdi 0000000000000060 popq %rbp 0000000000000061 jmp _NSStringFromClass
otool -tV -arch x86_64 DemoApp.app/DemoApp | grep Deadpool
0000000100001a70 movq 0x22c9(%rip), %rdi ## Objc class ref: Deadpool 0000000100001a7e movq 0x158b(%rip), %r12 ## Objc message: +[Deadpool new] -[Deadpool(Guns) guns]: -[Deadpool name]:
Source: https://habr.com/ru/post/283570/
All Articles