DevPrep

All topics › Objective-C

How does objc_msgSend work, and selector caching?

Senior PRO

What objc_msgSend does

objc_msgSend(id self, SEL _cmd, ...) is the entry point of every message send. It is not an ordinary C function but hand-written assembly for each architecture (arm64, x86_64), because it must:

  1. check self for nil (and tagged pointers) — if nil, zero the result registers and return;
  2. fetch the class from isa (masking the non-pointer isa);
  3. look up the IMP in the class cache by selector;
  4. tail-call (jump) into the found IMP without touching the argument registers — so the IMP sees the same self, _cmd and parameters as if it had been called directly, and objc_msgSend leaves no stack frame.

Without assembly it would have to copy an arbitrary number of arguments while knowing the signature — and the signature is exactly what objc_msgSend does not know.

Variants: objc_msgSendSuper (for [super ...] — searches from the superclass but self stays the same), objc_msgSend_stret (returning a large struct through a hidden pointer, unnecessary on arm64), objc_msgSend_fpret (x86 for long double).

The rest of this answer, with code and interview follow-ups, is in the DevPrep app.

Read the full answer in DevPrep

Practice this before your interview

DevPrep turns these answers into one-minute challenges: what does this code print, find the bug, mock interviews. One challenge a day.

Get DevPrep on the App Store