How does the Objective-C runtime retrieve the list of classes and methods?

混江龙づ霸主 提交于 2019-12-03 02:48:28

The compiler, linker, and runtime work together.

First, the compiler parses the source code for each class and emits directives like .long, .zero, and .quad describing the class's instance variables, properties, selectors, and methods. The assembler turns these directives into raw data.

The data is in a format that the runtime understands. For example, the data starting at symbol OBJC_CLASS_$_MyClass matches the layout of the runtime's struct class_t (defined in objc-runtime-new.h). The data at symbol l_OBJC_CLASS_RO_$_MyClass matches the layout of the runtime's struct class_ro_t (although most of the fields are 0 because the runtime updates them when it loads the class). The struct class_ro_t has a baseMethods field of type method_list_t *, which in the case of l_OBJC_CLASS_RO_$_MyClass is initialized to l_OBJC_$_INSTANCE_METHODS_MyClass. At l_OBJC_$_INSTANCE_METHODS_MyClass you will find data laid out like a struct method_list_t, which ends with an array of struct method_t - one for each method in the class. In your example, it's not very interesting because each of your classes has only one method.

The compiler uses the .section directives to tell the linker how to group chunks of that data together. For example, all of the struct class_t chunks will be put together in a section named __objc_classlist. This way, the runtime can just look up the section named __objc_classlist, and then process the entire section as an array of struct class_t. Take a look at the GETSECT macro in objc-file.mm.

The linker arranges for the function _objc_init (in objc-os.mm) to run very early in the lifetime of your process, before main. The _objc_init function registers some callbacks with the dynamic loader. In particular, it tells the loader to call map_images (in objc-runtime-new.mm), which calls map_images_nolock, which eventually calls _read_images. The _read_images function actually parses those chunks of data emitted by the compiler and turns them into the data structures that objc_msgSend uses to actually send messages to objects.

You can download an archive of the Mac OS X 10.8 Objective-C runtime source code to learn more. This archive also contains source files for iOS/ARM (and even Windows!), although it might not correspond exactly to any version of iOS.

It's not that the runtime knows how to read your program, but that the objc front-end translates the code base to use the runtime.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!