Как известно, селекторы в Objective-C - это уникальные адреса строк в памяти, которые используются objc_msgSend
для диспетчеризации сообщений. Уникальность обеспечена неким механизмом интернирования. При этом он работает как на этапе компиляции (директива @selector
), так и во время выполнения программы (функция sel_registerName
или NSSelectorFromString
). Пытался понять как это работает - получилось.
Все банально просто - компилятор создает отедельную секцию __objc_selrefs данных для всех селекторов, используемых ключевым словом @selector
:
;
; Section __objc_selrefs
;
; Range 0x100002678 - 0x1000026a0 (40 bytes)
; File offset 9848 (40 bytes)
; Flags : 0x10000005
;
objc_sel_point:
0000000100002678 dq 0x00000001000019c4 ; XREF=0x100001485, 0x100001543
objc_sel_init:
0000000100002680 dq 0x00000001000019de ; XREF=0x100001607, 0x1000016b8, 0x10000170c, 0x1000017a7
objc_sel_setHelloText_:
0000000100002688 dq 0x00000001000019e3 ; XREF=0x100001633, 0x1000016d3, 0x100001727
objc_sel_stringWithFormat_:
0000000100002690 dq 0x00000001000019f1 ; XREF=0x10000167d
objc_sel_description:
0000000100002698 dq 0x0000000100001a18 ; XREF=0x1000017d4, 0x1000018eb
Ну, а sel_registerName
возваращает элемент из этого списка, если он найден, в противном случае - адрес строки из какого-то динамического списка времени выполнения.
Есть еще нюанс - работает ли @selector
сквозь модули? Подозреваю, что нет.