« Really Getting Things Done | Main | Out of hiding and into the fire »
June 14, 2005
NSBindingDebugLogLevel
One of the small lab victories to come out of WWDC was getting NSBindingDebugLogLevel working with our projects. As marvelous as Cocoa Bindings are, if you've got a mistyped key in a nib file, it can be a real pain to track down. NSBindingDebugLogLevel was supposed to be the answer, but neither Dan nor I could get it to work.
It turns out that we each had a .gdbinit file in our home directories that specified fb -[NSException raise]. Normally this is a good thing since we like to break on exceptions without having to set the breakpoint every time we reset our individual pbxuser files. However, and here's the answer, breaking on raise stops gdb before the bindings log gets a chance to print. Since we had the breakpoint in a set-and-forget external file, the bindings log never appeared.
So, good bye .gdbinit. Hopefully Xcode 2.1 won't require trashing my pbxuser file quite so often.
Thanks to the Core Data team for helping me track this down.
Update: I should add my preferred way of setting the option. In Xcode, add the argument -NSBindingDebugLogLevel 1 to the target's executable and flip on the switch.
Posted by ttalbot at June 14, 2005 11:36 AM
Comments
Just to clarify: Unlike the release notes at http://developer.apple.com/releasenotes/Cocoa/AppKit.html -- it's not a user default, it's an argument. No wonder I couldn't get it to work!
Posted by: Dan Wood at June 14, 2005 11:12 AM
Actually, I think either will work. I just like to set it as an argument on the executable from within Xcode so that I have a visible reminder of its state. What was stopping us was really the (hidden) break on [NSException raise].
Posted by: Terrence Talbot at June 14, 2005 11:56 AM
You can wrap your gdb_init commands in a gdb function. Then you call the function when you want to set breaks on raise. Here's my .gdb_init:
echo ### GDB is executing .gdbinit\n
define SetCocoaDebuggingBreakpoints
echo ### JIW Setting Cocoa Breakpoints\n
future -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:]
future -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
future -[NSException raise]
echo ### JIW Setting Cocoa Breakpoints Done\n
end
define SetNotificationBreakpoints
echo ### JIW Setting Cocoa Breakpoints\n
future -[NSNotificationCenter removeObserver:]
future -[NSNotificationCenter removeObserver:name:object:]
future -[NSNotificationCenter addObserver:selector:name:object:]
echo ### JIW Setting Cocoa Breakpoints Done\n
end
future _NSKVODeallocateLog
#SetCocoaDebuggingBreakpoints
Also - I'm surprised NSBindingDebugLogLevel doesn't work as a user default. Arguments in Cocoa _are_ user defaults (they're just in a different domain - NSArgumentDomain - from the defaults found in application's plist).
Posted by: Jonathan Wight at June 16, 2005 8:14 AM