I recently had to debug a complex Responder Chain-related bug:
Did you know that when you send a nil-targeted action message, but there’s no first responder, the chain is started from the sender of the message? It seems to make sense, but I can’t find mention of it in the documentation.1
Anyway, I ended up writing a few utility methods to help me track this bug. Here they are:
@interface UIView (NBResponderChainUtilities)
- (UIView*) nb_firstResponder; // Recurse into subviews to find one that responds YES to -isFirstResponder
@end
@interface UIApplication (NBResponderChainUtilities)
- (UIView*) nb_firstResponder; // in the -keyWindow
@end
@interface UIResponder (NBResponderChainUtilities)
- (NSArray*) nb_responderChain; // List the -nextResponder starting at the receiver
@end
UIView * NBFirstResponder(void); // in the app key window
NSArray * NBResponderChain(void); // Starting at the first responder
Armed with this, you can simply po
the responder chain in the debugger:
(lldb) po NBResponderChain()
$13 = 0x213dda70 <__NSArrayI 0x213dda70>(
<UIActionSheet: 0x11915160; frame = (0 231; 320 337); opaque = NO; ...
<UIView: 0x222c73b0; frame = (0 0; 320 568); opaque = NO; layer ...
<UIView: 0x2229d340; frame = (0 0; 320 568); opaque = NO; layer ...
<UIView: 0x11913dc0; frame = (0 0; 320 568); clipsToBounds = YES; ...
<_UIAlertOverlayWindow: 0x2226d4e0; frame = (0 0; 320 568); layer ...
<UIApplication: 0xaa66b30>,
<BicycletteApplicationDelegate: 0xab78c60>
)
It is available as a gist.
Enjoy and share; comments are welcome, via nico@bou.io or on twitter.
-
If I lost you at “nil-targeted”, go read the docs. The Responder Chain is one of the most powerful features of Cocoa(Touch), but it’s largely being ignored on iOS. ↩