It is time for me to clean up the complete Objective-C messaging flow1 for myself and to keep a record for later reference.
NilTest: if receiver is nil, return nil.
CacheLookup: look up IMP in per-class dispatch cache table, use it if found.
MethodTableLookup & lookUpImpOrForward:
- Look up IMP in class hierarchy bottom-up, cache it and use it if found.
- Try Dynamic Method Resolution:
+resolveClassMethod:. Step 3.1 will be tried again afterward.
- Try Fast Message Forwarding — Selector Forwarding:
- Try Slow Message Forwarding — Invocation Forwarding:
- Finally, if nothing above helps,
-[NSObject forwardInvocation:]) and
-respondsToSelector:use Message Forwarding?
-respondsToSelector:use Dynamic Method Resolution?
- Why? And why Dynamic Method Resolution is tried before Message Forwarding?
- Why is
-methodSignatureForSelector:required for Invocation Forwarding?
- Dynamic Method Resolution adds real method IMP into dispatch table and thereafter it has no difference from statically implemented method at all to the runtime — it is one-off indirection and fallback. Message Forwarding is lifetime indirection and fallback.
- To pack and unpack arguments. Method signature is just type encoding wrapped in object. Invocation creating is message recording, which is a data archiving process. Invocation forwarding is message replay, which is a data unarchiving process. To unarchive the archived data, type information of the data is necessary.