Cocoa and messages to nil, revisited
Cocoa and messages to nil, revisited
- Subject: Cocoa and messages to nil, revisited
- From: Jeff Laing <email@hidden>
- Date: Wed, 8 Aug 2007 09:35:18 +1000
With regard to recent messages about whether 'messaging to nil silently
works' is a good thing or not, I took a deeper look at the Objective-C
runtime library sources on apple.com.
It turns out that the runtime *does* support an application installing a
hook object which will receive all messages sent to nil. The following code
works, at least on my 10.4 Intel machine.
-----------------------------------8<-------------------------------
#import <objc/Object.h>
@interface nil_receiver : Object {}
@end
@implementation nil_receiver
+ (void)install { _objc_setNilReceiver([nil_receiver new]); }
+ (void)remove { [(id)_objc_setNilReceiver(nil) free]; }
- doesNotRecognize:(SEL)aMessage { NSLog(@"[nil_receiver %s]",aMessage);
return nil; }
- (oneway void)release { }
- (id)autorelease { return nil; }
- (id)retain { return nil; }
- (id)copyWithZone:(NSZone*)z { (void)z; return nil; }
- (bool)isKindOfClass:(Class)c { (void)c; return NO; }
- (bool)respondsToSelector:(SEL)m { (void)m; return NO; }
@end
@implementation MyAppDelegate
- (void)applicationWillFinishLaunching:(NSNotification *)aNotification
{
#pragma unused(aNotification)
[nil_receiver install];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification
{
#pragma unused(aNotification)
[nil_receiver remove];
}
-----------------------------------8<-------------------------------
but ultimately it doesn't help you out. Cocoa sends messages to nil like
they are going out of style, so the above generates reams of output, even in
my "I know that I never send messages to nil" testbed application.
What it *might* be useful for is that if you think you have a specific
problem, you could replicate its methods and have them individually NSLog()
or breakpoint or whatever, rather than rely on the doesNotRecognise: handler
- or you could silence more and more of the messages that Cocoa sends itself
and hope that your problems are in messages that aren't in that set.
Initially all I included was doesNotRecognise: but Cocoa likes to NSLog()
about an "Object compatability layer that you need to remove now" if you
don't implement the release/autorelease/etc messages.
Conclusion: whilst Objective-C does provide tools that might allow you to
catch unexpected messages to nil, the Cocoa frameworks make it useless due
to their reliance on it internally.
(As a performance junkie, its disappointing that people still think that its
quicker to just send the message to nil, than to do "if (target) [target
message];" since it doesn't matter *how* fast you make that message
dispatcher, it can't possibly be faster than the two instructions that the
conditional takes, especially since deep in its bowels we can see the
message dispatcher doing the exact same test, but then taking a much longer
execution path in either case)
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden