Snow Leopard + WebKit + GC + CSS? Nope.

UPDATE: I’ve belatedly realize that although I quote the bug, I probably make it sound like this bug relates to all dynamic CSS, which is not the case.  In general it’s probably pretty rare to find random CSS code on the web that will trip the bug.  That said, if you are using Apple’s excellent Dashcode tool to create your HTML/CSS/JS, it’s actually pretty hard NOT to trip the bug.

Recently I was using a WebKit to serve up some static content in my Snow Leopard only, garbage collected app, when I ran into a crash with a call stack winding through WebKit and ending in an errant CFRelease.

The crash manifested whenever I tried to change CSS properties from JavaScript called back from my Objective-C code (via the WebKit WebScriptObject interface).  Pretty quickly, I realized that I could also get the crash to happen from JavaScript code changing CSS properties in a vanilla JavaScript timer callback, or pretty much any JavaScript code post page load / initial page render for that matter.

A good bit of WebKit source spelunking later revealed this little gem:

http://trac.webkit.org/changeset/50918

Thankfully, there is more than just the opaque reference to rdar://problem/7390716 (wonder what that bug is) and we get a reference to:

https://bugs.webkit.org/show_bug.cgi?id=31429

Which bottom lines to this little beauty:

“Crash when a CSS transition is run on a CSS transform in a GC supported or GC required build.”

Sweet.  I am alone in thinking that this means there is pretty much no way to use WebKit in a garbage collected (or even garbage collection supported for that matter) Mac application?

Oh, well, score one for open source; custom local build of WebKit.framework here I come!

Published in: on January 20, 2010 at 3:02 pm  Comments (5)  

Debugging Wierdness iPhone and Xcode

UPDATED: Filed a bug on this issue for any Apple folks reading this at rdar://problem/7590305.

Recently, at The Department, we experienced some problems debugging an iPhone 3.1.2 application written in a mix of Objective-C and C++ in Xcode (or the raw gdb console for that matter).

The symptoms were that while the app would run and we could set and hit breakpoints, attempting to browse locals or “p” or “po” in gdb while in a breakpoint would just report total garbage.

The app in question is split across multiple static libraries in multiple Xcode project files.  To complicate things even more, there are multiple targets for different platforms in the various projects (iPhone, simulator, Mac OS).

Initially, it seemed like maybe the problem was relating to the multi-target, multi-platform project structure.  It was certainly not easy to coax all these targets and platforms into the various projects, and is not a generally not recommended practice in the first place, but boy is it convenient!

Luckily we found we could reproduce the same debugging problem in a simple test application.  To replicate, we just created a fresh project using iPhone OS “Application” template called “Window-based Application”.  We just added two simple classes, one C++ and one Objective-C class, each with a handful of member variables.  Next we added instances of those two classes as member of the AppDelegate Objective-C class generated by Xcode. Set a breakpoint and run on the target device in the AppDelegate’s initializer and boom!  Garbage locals.

The weird part is that reproducing the same steps using the iPhone OS “Application” template called “OpenGL ES Application” worked fine.  No garbage locals when debugging.

Using trusty Araxis merge to compare the two project files, we spotted one minor difference in the two Xcode generated projects. The line:

"GCC_THUMB_SUPPORT[arch=armv6]" = "";

was present in the project that we could see locals for, but not in the one that resulted in garbage locals in the debugger.

After adding this line into the non-working project, everything worked great in the debugger. No problem seeing locals.

Weirdly try as we might, we were not able to figure out a way to get the Xcode user interface to add this line to our bugged out (but Xcode generated) project. And similarly, we were not able to figure out how a way to get the Xcode user interface to removed this line from a working project.  It seems this line needs to be added in by hand in the project XML (or appear in Apple’s project template in the first place).

Happily, we added this line to all our various Xcode targets and projects in our complex app and…everything now works great!

Published in: on January 20, 2010 at 1:33 pm  Comments (4)  
Tags: , ,

Garbage Collection and KVO and NSNotificationCenter, Oh My!

Recently, I ran into some problems with data dependencies and garbage collection in my bespoke model classes. Several classes in my model code register as observers of other model classes using either KVO or via NSNotificationCenter.

Although I’m using garbage collection, I was trying to be a good boy by implementing a dispose method on some of these model classes so that they could de-register as observers when they were no longer an active participant of the model.

The problem with this approach is that various Cocoa classes, such as NSUndoManager, don’t easily offer me the opportunity to invoke my dispose method (say for example when the redo queue is cleared by registering a new invocation). There are a few different solutions to the problem. In my case, registering the “activation” and “deactivation” of my model classes (i.e. the adding and removing of themselves as observers) with the NSUndoManager is the one I opted for.

In the course of implementing this code, I played around with using NSObject's finalize method as a way to de-register my observers, rather than inducing the undo manager to invoke my own dispose method. Generally speaking, I try to stay away from finalize methods in garbage collected languages, and Objective-C is no exception. Apple cautions against the madness of using finalize methods for performing any serious work.

All that said, it got me thinking about where exactly Apple expects objects to de-register their KVO and NSNotificationCenter observers in the general case. The problem with remove observers in finalize methods are several:

  1. You are forced to introduce a finalize method where you otherwise wouldn’t have to. Not good for performance and can open up a Pandora’s box of non-determinism.
  2. The finalizer’s of objects collected in the same cycle are not guaranteed to run in any particular order. So de-registering object A as an observer of object B in object A’s finalize method might happen after object B is already collected (i.e. when it’s invalid), leading to “Cannot remove an observer … for the key path … from … because it is not registered as an observer.”
  3. The de-registration of observers happens at a non-deterministic time (i.e. whenever the garbage collector gets around to running).

As far as items #1 and #2 are concerned, there is a better way, which is (wait for it…) to do nothing.

From the docs on NSNotificationCenter's addObserver:

“As a convenience, when built with garbage collection, you do not need to remove any garbage collected observer as the system will do it implicitly.”

And as of the November seed of 10.6, this is also now true of KVO. The seed note “Automatic Removal of Finalized Key-Value Observers When Running Garbage-Collected (New since November seed)” describes the following:

“In Mac OS 10.6, explicit removal of observers when they’re finalized is now never necessary. KVO automatically removes observers as they’re collected. Actually, in Mac OS 10.6 all invocations of -[NSObject(NSKeyValueObserverRegistration) removeObserver:forKeyPath:] and -[NSArray(NSKeyValueObserverRegistration) removeObserver:fromObjectsAtIndexes:forKeyPath:] do virtually nothing when either the receiver or the observer is being finalized (so it’s not very bad for performance to leave them there in applications that still have to run on Mac OS 10.5).”

So at least in Snow Leopard after the November seed, you can just let it ride and the system will take care of cleaning up your KVO and NSNotificationCenter registrations.

As for item #3, well it’s either playing games with regularly invoking NSGarbageCollector's collectExhastively or implementing a dispose pattern.

Published in: on October 23, 2009 at 8:56 am  Comments (1)  
Tags: , , , ,

Frameworks with Private Frameworks

Recently, in my infinite wisdom, I decided I wanted to have a framework that embeds a private framework.   Frameworks, are those are uber-cool versions of DLLs complete with multiple versions, public headers, dynamically linked object code, etc for you recent Cocoa converts following along at home.

Before I get started, you may be asking, why ever would I want to do this?

Well, my application is distributed (err, planned to be distributed) with a set of plug-ins that live in the application’s bundle.  One of the plug-ins wants to use a framework common to my organization, but not public.  I don’t want to develop an installer to put the framework the plug-in needs in the system or user’s library, especially because it’s private to my plug-in’s implementation.

Ok, now that THAT’s out of the way, let’s get back to the subject at hand.  When I first started splitting my code up into frameworks I was surprised to learn that the dynamic library at the heart of a framework actually embeds the path it expects to be installed at.  Generally speaking having the absolute path of where the framework expects to be installed is not that big a deal, and helps lift OS X out of DLL hell.  There are only a handful of standard places you should be putting your framework (such as $HOME/Library/Frameworks, etc).

Since frameworks can contain multiple versions of their code, the DLL hell that .NET helps clean up with the GAC is largely obviated.  The main downside to installing your framework in a standard location is well, just that, the installation part.

If your framework is unlikely (or not intended) to be used by more than your one application, a nice alternative to installing it in a standard location is to embed it in your application’s bundle.  The standard place for this is in the MyApp.app/Contents/Frameworks directory inside your bundle.

The catch is that you don’t really know where the application is going to be copied by the user (when they say drag/drop it from the .dmg disk image that you distributed it in).  The problem with not knowing where it’s going to be copied, is that pesky hard coded path inside of the dynamic library (the one used by the linker to bake references to it into your application).

Fortunately, starting with OS X Tiger, you can use a the string “@executable_path” in the hard coded installation path of your framework.  Assuming that you plan to put your private framework in the standard place in your application bundle (the MyApp.app/Contents/Frameworks directory) that path is typically “@executable_path/../Frameworks”.  When the dynamic linker attempts to locate the library at runtime, it substitutes the path of the current executable in place of, you guessed it, “@executable_path”.  That’s likely to be something like /Applications/MyApp.app/Contents/MacOS.

So far so good.  And so far, pretty reasonably documented by Apple.

Now, back to those plug-ins.  The plug-ins are themselves frameworks; frameworks that uses other frameworks.  Both the standard Cocoa ones, and also the private one-off kind.  The symbolic constant “@executable_path” isn’t too much help to us here because we can’t say for sure where the plug-ins are going to live relative to the application.  I suppose for my originally stated “plug-ins distributed in the bundle of my application” case I could come up with some really knarly relative path, but what about user installed plug-ins?

There are a few different reasonable places (and I’m sure quite a few unreasonable places) that plug-ins might live on the user’s system.  Here again Apple provides nice documentation to describe the details and best practices.  So really, “@executable_path” is not quite what we’re looking for.

Thankfully, “@executable_path” has a little less well known friend named “@loader_path”.  This friend is exactly the kind of friend we need to implement frameworks with private frameworks.  As you may already be able to guess, “@loader_path” is resolved by the dynamic linker at load time to the path of the dynamic library inside the framework bundle (i.e. my plug-in) that is actually doing the loading.

The standard place to put a private framework inside of another framework is “MyCoolPlugin.framework/Versions/Current/Frameworks” (although as per the Apple documentation, your plug-in should pick a unique extension, and not be named with the “.framework” extension).  Since the actual dynamic library lives as a direct peer to the “Frameworks” path (rather than under a sub-directory like “MacOS”) the typical installation path for the private framework used by another framework is “@loader_path/Frameworks”.

And there you have it, frameworks with private frameworks!

Published in: on August 2, 2009 at 10:40 pm  Comments (5)  

Two-Way Data Binding in Cocoa

Coming from the .NET world, it seems strange to me that for whatever reason, bi-directional data binding isn’t supported out of the box in Cocoa.

The various provided standard controllers effectively implement two-way data binding. Take for example NSArrayController's contentArray. When binding NSArrayController's contentArray to a collection in your own data model, the NSArrayController uses Cocoa’s KVO based binding technology to observe changes to your data model. Coming to Cocoa with experience from other data binding technologies, this is pretty straightforward and expected behavior.

NSArrayController also pushes updates to your data model, but not through Cocoa’s binding technology. In the reverse direction, NSArrayController caches the information passed to it when a data binding is established. This cached information is used to force feed updated values to the source of the data binding via Cocoa’s KVC technology. It wasn’t initially clear to me that this was being accomplished “manually” by the NSArrayController and that this bi-directional behavior wasn’t something I could expect to happen automatically when implementing my own controllers.

Apple’s documentation doesn’t touch on strategies to implement the kind of two way communication that their standard controllers evidence that I could find. In fact, Cocoa Bindings Programming Topics doesn’t really have a lot to say on the subject of implementing your own controllers at all. As usual, I found solace via Google and the Cocoa community. In particular I found this clear and brief CocoaHeads México presentation to be a really helpful addition to Apple’s documentation when getting up to speed on implementing custom controllers.

Fortunately, Apple’s sample code does a great job of showing an example of implementing a custom controller that performs this kind of two way communication. The BindingsJoysticks sample demonstrates the pattern of overriding your custom controller’s bind implementation and caching the source object and source key path of the bind.

An advantage of the “manual” implementation of the back flow of data from controller to source in Apple’s sample code is a high degree of flexibility and control over exactly when the source of the data bind is updated by your controller. In fact, you can choose to have your source object and your controller be out of sync from each other for a period of time (or forever) if that floats your boat. This can be pretty useful in various situations (interactive mousing with undo/redo comes to mind), but can also be harder to maintain and downright cryptic to a consumer of the controller.

A fairly obvious downside to “manually” implementing the back flow of data from controller to source is, well, the manual part. The extra typing isn’t so bad if you are implementing your one true controller to rule them all, but if you have a number of properties you want to bind, it can be pretty tedious. Consider for example, implementing in the style of Model-View-View/Model (MVVM).

In MVVM, it’s typical to use data binding to glue your view to your view model without either being the wiser. Having not built a large scale Windows Presentation Framework (WPF) application (whose API is architected around the MVVM pattern) I never really got the Kool-Aid pumping through my veins. Proponents of MVVM believe it makes it easier to iterate on user interface, easier to perform headless automated testing of UI functionality, and provides overall more scalable and maintainable implementations. If you are interested in learning more about MVVM, some links to check out are:

In MVVM, there are often a relatively large number of properties across a number of objects that need to be bound to each other. Manually implementing two-way data binding for each such object can be kind of a drag. For that reason, I threw together a little utility class to handle the back flow of values from controller to source (or View to View-Model) for me. The sample code is available at Cocoa Convert on Google Code.

A few caveats before I go on: this is definitely not production code and I use garbage collection. In other words, no effort has been put into retaining objects appropriately and it’s probably a very bad idea to drop this into your own project as is.

An instance of the TwoWayBindingManager class is owned by your custom controller:

#import "TwoWayBindingManager.h"

@interface MyController : NSObject 
{
@private
  ...
  TwoWayBindingManager* _twoWayBindingManager;

It is instantiated when your controller is initialized, and should be disposed of when your controller is disposed of (either in a custom dispose method, or when not using garbage collection in a dealloc):

- (id)init
{
  if([super init] == nil)
    return nil;

  _twoWayBindingManager = 
    [[TwoWayBindingManager alloc] initWithObject:self];

  return self;
}

- (void)dispose
{
  [_twoWayBindingManager dispose];
  _twoWayBindingManager = nil;
}

Your custom controller then needs to override bind and unbind and give the TwoWayBindingManager instance a chance to hook in:

- (void)bind:(NSString *)bindingName
    toObject:(id)observableController
 withKeyPath:(NSString *)keyPath
     options:(NSDictionary *)options
{	
  [super bind:bindingName
	 toObject:observableController
  withKeyPath:keyPath
      options:options];

  [_twoWayBindingManager bind:bindingName
					 toObject:observableController
				  withKeyPath:keyPath
					  options:options];
}

- (void)unbind:bindingName
{
  [super unbind:bindingName];
  [_twoWayBindingManager unbind:bindingName];
}

From the controller side, that’s it! As far as usage goes, you just need to pass in the extra option kWantsTwoWayBinding for any bindings that you want to be bi-directional:

[cont bind:@"someControllerProperty" 
  toObject:self 
 withKeyPath:@"someSelfProperty"
   options:[NSDictionary dictionaryWithObjectsAndKeys:
  		    [NSNumber numberWithBool:YES], 
		    kWantsTwoWayBinding, nil]];

The major trade-off of the TwoWayBindingController approach is less flexibility and control over how closely synchronized the properties of your custom controller are kept to your data source. For situations where you are willing to trade that kind of control for the ease of bi-directional data binding, an approach like the TwoWayBindingController may just save you a lot of typing and bug hunting!

The sample code accompanying this article is available at Cocoa Convert on Google Code.

Published in: on May 31, 2009 at 10:16 pm  Comments (3)  
Tags: , , ,

Flippin’ Modal Panels

Apple’s Keynote has a cool and efficient UI paradigm on application start-up. It displays a panel with a collection of themes from which to start a new presentation, but also has a button on the panel to choose an existing presentation. Pressing the choose existing presentation button performs a panel flip animation to reveal the common system open panel. Canceling from the open panel results in a flip animation back to the theme chooser panel.

Keynote Flip

Start-up screens are ubiquitous, but I haven’t seen the addition of the open existing button before. It’s a small thing, but it saves the user the annoyance of having to hit cancel and then File/Open. The flip has also got that cool gratuitous Apple bling thing going on.

I’d implemented the flip effect using Core Animation previously in the context of a small item embedded in a larger super view, but that was flipping CALayers, not NSWindows. Also, we’re talking about messing with modal windows to boot, including one that isn’t real sub-class friendly: NSOpenPanel.

A quick consultation with Google turned up two different existing implementations of flipping NSWindows:

Both look well implemented and are conveniently packaged up as a category on NSWindow. Both seemed to be showing their age a little though as they chug based on their image manipulation technology. It also wasn’t immediately obvious how to get either of them to work easily with NSOpenPanel.

I decided to take a (very) similar approach to the existing implementations, but to use Core Animation to do the flipping for me and to tweak the setup and tear down to work better with the modal system panels. The key idea I took away from the previous implementations was creating an over-sized, non-opaque window in which a screen shot of the window being flipped would be animated.

The code for creating an over-sized non-opaque window is very straightforward:

NSRect overSizedBounds =
  NSInsetRect([windowToFlip frame], -100, -100);

_flipWindow =
  [[NSWindow alloc] initWithContentRect:overSizedBounds
  		 			  styleMask:NSBorderlessWindowMask
						backing:NSBackingStoreBuffered
						  defer:NO];
[_flipWindow setOpaque:NO];
[_flipWindow setHasShadow:NO];

Taking a screen shot of the existing window also turns out to be pretty easy:

NSView* view = [[[self window] contentView] superview];

NSRect bounds = [view bounds];
NSBitmapImageRep* bitmap =
  [view bitmapImageRepForCachingDisplayInRect:bounds];

[view cacheDisplayInRect:bounds
        toBitmapImageRep:bitmap];

Displaying the screen shot in the over-sized window using Core Animation is neat and clean. I used setWantsLayer to request the content view of my over-sized window be layer backed, and then created a new CALayer and added it as a sub-layer to the over-sized window.

The nested CALayer avoids having to mess with layer backing the NSView, which really doesn’t like to be messed much with. There’s probably some room for potential improvement in moving away from a layer backed view. The sub-layer holds the screen shot of the window being flipped, which thanks to the contents property of CALayer and the [NSBitmapImageRep CGImage] convenience method is also dead simple to implement:

NSView* flipView =
  [[NSView alloc] initWithFrame:bounds];
[_flipWindow setContentView:flipView];

[flipView setAutoresizingMask:
  (NSViewWidthSizable|NSViewHeightSizable)];
[flipView setWantsLayer:YES];

_flipLayer = [CALayer layer];
[[flipView layer] addSublayer:_flipLayer];
[_flipLayer setFrame:bounds];

[_flipLayer setContents:(id)[bitmap CGImage]];
[_flipLayer setContentsGravity:kCAGravityCenter];

The flipping code is just a CABasicAnimation that animates transform.animation.y from zero to PI/2. The only minor gotcha to remember is to set up perspective in the transform matrix

CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0 / -850;
[_flipLayer setTransform:transform];

What I spent most of my time on was working to eliminate flicker. Initially, I assumed I could just wrap any transitions between the “real” windows and the “fake” over-sized window with calls to NSDisableScreenUpdates() and NSEnableScreenUpdates().

While those calls were definitely a big piece of the puzzle, I also had to be careful to force the initial display of the window ([NSWindow display]) to occur while updates were disabled. I also had to pay attention to the relative window levels as I was dealing with modal sheets. Both of these ideas are present in the two example programs cited earlier, but the modal sheets, timing and granularity of the delegates from NSOpenPanel and CABasicAnimation took some tweaking.

The last problem I encountered in replicating the silky smooth flip of Apple’s Keynote start-up template screen was some hitching around the point of transition due to setup and tear down cost. Again the solution was present in the example programs cited earlier, but I had to futz around with it a little based on Core Animation and modal timings and delegates.

In short, the solution was to use NSPanel's setAlphaValue: to hide the latency of window creation, screen shot creation and the setting of the contents of the CALayer. After the flip is completed from panel “A” to panel “B”, and panel “B” is presented to the user I perform the setup of the overlay window in anticipation of the next flip. This means I take a screen shot of panel “A” (without actually displaying it to the screen) and set the over-sized window up (also without displaying it to the screen), but setting it’s alpha value to zero so it remains invisible until it’s needed.

It’s easy to notice a hang in the middle of the transition animation, but it’s much harder to notice that the app is hanging at the end of the flip animation. In the latter case, the hang “hides” in the time it takes to visually parse the newly presented contents.

Big caveat: I’m targeting Leopard only and it’s not immediately obvious to me which aspects of the approach I took would fail on which previous versions of OS X. Both of the previously cited examples are approaches that work on past versions of the OS and older hardware, and seem like a good way to go if that kind of support is needed.

Hmm, now what important feature was I supposed to be implementing instead of working on eye candy? Flippin’ !#@$% modal panels.

Published in: on May 24, 2009 at 1:23 am  Comments (22)  
Tags: , ,

Pattern Muscle Memory

Sometimes I catch myself applying a particular pattern in an architecture / application design almost without consciously thinking about it. One of the side benefits of flailing around in Cocoa and Objective-C is the disruption of my “pattern muscle memory”.

A recent example is in the implementation of the model layer of the graphical authoring tool I’m working on. One very basic required feature is the ability to delete a graphical element. The element can be deleted in the usual ways: the user pressing the delete key, the user selecting delete from the edit menu, etc. These actions ultimately invoke the same code and remove the item from the data model. There are other ways that the element might be deleted too: as a result of a cut operation, as the result of a synchronization or merge operation with an external source (like importing data from another file), etc.

My pattern muscle memory would normally have me tackle the ability to undo/redo this operation using classic “gang of four” style command and memento patterns; creating concrete implementations of an abstract command for each action.

In this case, being a new Cocoa programmer, my C#/.NET pattern muscle memory was disrupted by the NSUndoManager’s cool ability to package up “ordinary” invocations rather than requiring any special sub-classing or glue code. Now, I could certainly implement this kind of thing in .NET using reflection, etc, but I would have to implement it rather than using it “off the shelf”. Besides, my pattern muscle memory would have kicked in before I really had given it too much thought.

For my delete implementation, I chose to use one of the common Cocoa approaches exemplified in Aaron Hillegass’ book of using KVO to observe the removal of the object from it’s collection and registering it’s inverse (an insertion) on the undo stack. When KVO tells me that the object was added, I register the inverse of that operation (a deletion) on the undo stack.

One common challenge I’ve faced in the past is what to do about side effects or otherwise dependent actions of the principal action occurring. In the case of deleting my graphical object, there are several side such effects. One example is the need to modify connected or constrained graphical objects. In certain situations, an extreme side effect is the need to delete or create related objects, allocate unique identifiers, etc.

My pattern muscle memory typically has me encapsulate these dependent actions along with the implementation of my original user operation, in this case, the delete. One complication of this approach is that as the application scales and multiple developers work on the code base, it can be hard to ensure that everyone consuming the model uses the same high level delete implementation.

In the case of the delete key, the delete menu item, etc, it’s dead simple to make sure the same high level code (with it’s encapsulated side effect behavior) is invoked. As more complex features (such as the merge example) find themselves needing to delete the graphical object (along with performing all of it’s side effects) the requirement to use the common high level delete implementation can get obscured. Especially when the various types of consumers haven’t been anticipated in the design of the model’s API. I’ve found the murkiness (and naughtiness) increases when a generalized data model framework is being used, as it invites direct access to manipulating the data model via it’s APIs. Such is definitely the case with Core Data.

In the past, my pattern muscle memory has had me implement intermediate model layers that encode the side effects, but it has always seemed like such a waste of time and effort to obfuscate direct access to the generalized data model framework APIs with intermediate layers.

In my Cocoa implementation, I choose to implement my data model side effects in KVO observers. I did this so that deleting my graphical element using the Core Data API results in the requisite side effects and dependent data model changes. The main reason I did this is to avoid requiring special discipline or knowledge of the side effects on the part of the consumer of the model. My KVO observers however, also implement the undo/redo registration as I touched upon above. The problem with this approach when naively done is the exponential accumulation of invocations in the undo and redo queues. Each KVO notification from successive undo and redo operations results in performing the side effects and dependent operations anew (in addition to the queued undo/redo invocation).

This is easily rectified by checking to see if our KVO notification is happening as a result of an undo/redo operation (i.e. [NSUndoManager isUndoing] or [NSUndoManager isRedoing]) before performing side effects and dependent operations. If we are in the midst of an undo or redo, we let the invocations on the queue take care of the side effects and dependent operations, but don’t ourselves reissue them as a result of the KVO notification.

Sure I could have implemented all this in C# / .NET, or Java or JavaScript for that matter, but it’s not set up “out of the box” for it, and besides, my pattern muscle memory would have kicked in first anyway.

The bottom line result is a clear and compact model implementation that is easier to implement, extend and maintain over time, one that does not constrain it’s consumers to specialized APIs or require specialized knowledge.

Well, at least that is the theory… Time will tell, but for now I am love-hating my pattern muscle memory disruption.

Published in: on May 20, 2009 at 11:28 pm  Comments (1)  
Tags: , , , ,

Faulting Fun

Managed memory is awesome. Generally speaking, I would rather gouge my eyes out than go back to manually allocating memory.

It’s not that I can’t do it. I’ve been programming for long enough that I started out manually managing memory in the progression from 6502 assembly to C to C++, etc. True, the past few years I’ve been much farther away from embedded system code than I used to be in the days of the Super Nintendo, Atari Jaguar, PlayStation, et al. It’s just that I’d rather spend my time expressing “big ideas” (cue eye rolling now) than tweaking out string memory management on my sub three pound laptop with 4GB of memory.

I’m not sure I would be able to handle Cocoa and Objective-C programming without automatic memory management, but one recent friction point in my love affair with the Cocoa APIs is the dawning realization that there are a ton of subtle API architecture and implementation choices that were made before the move to Objective-C 2.0 and managed memory.

I’m not talking about fundamental incompatibilities between Cocoa API architecture and managed memory. I’m just talking about stumble inducing speed bumps.

A recent example I’ve tripped over is in combining Core Data and KVO. I am using both raw KVO and data binding heavily to glue together Core Data with the view model and view of the application I’m working on. In one instance, when a Core Data document (well, really an associated NSManagedObjectContext) is loaded, I execute a fetch request to obtain a set of peer “root” NSManagedObjects. I then register to observe some relationships and attributes on the resultant NSManagedObjects via KVO and then continue on with the rest of the application.

Later during the program, when new “root” NSManagedObjects of this particular entity type are created, I do the same thing (i.e. register to observe some relationships and attributes using KVO).

When attributes on these recently added “root” objects are changed, the user interface reflects the changes as expected, however when attributes on loaded “root” objects are changed, the user interface does not reflect the changes. WTF right?

After a curse filled hour or two (and copious amounts of caffine for focus) the problem turned out to be with my original fetch request and register using KVO. When I performed the fetch, I was not keeping a reference to the NSManagedObjects I obtained. Eventually after a garbage collection cycle or two, those initial NSManagedObjects were collected, and the underlying Core Data entity instances were turned back into fault (i.e. are dumped from memory). A very cool feature of Core Data, but very not ideal in this case.

When I later executed a fetch request to obtain one of these initially loaded “root” NSManagedObjects, Core Data created new NSManagedObject instances for me, bringing the data they represent back into memory from the persistent store. At this point, they are NOT the same NSManagedObject instances that I registered to observe with KVO (those instances are gone) because KVO did not keep strong references to the original objects, and neither did I.

Bottom line, while I am conceptually changing values on the same Core Data entity instances that I initially registered to watch with KVO, they are not actually the same NSManagedObject instances (thanks to garbage collection and the efficiency / coolness of Core Data dumping data from memory that’s not currently needed). Hence the lack of change in the user interface. The observed objects didn’t change, they were garbage collected!

In this case, it’s an easy fix; I just retain strong references to my “root” NSManagedObjects. I don’t really want these objects coming in and out of memory anyway.

I suspect had garbage collection been in heavy use by the designers and creators of KVO and Core Data when they were conceived and implemented, there might have been some subtle changes to their approach. Or maybe at the very least to the documentation.

I’m not really complaining; both of these systems are damn cool and when I’m not learning how to avoid tripping over my own feet, they are accelerating the crap out of my development.

Here’s looking forward to the days of less tripping per stride!

Published in: on May 19, 2009 at 6:19 pm  Comments (4)  
Tags: , , , ,

Self Observation

As far as I can tell, you can’t count on the order of observer registration for KVO to relate to order of notification. This is a bummer because it can lead to really subtle bugs for certain KVO and bindings patterns. My conclusion is to avoid those patterns, but if you’re interested in the details (and especially if you can point out a solution / flaws in my tests), read on!

In this particular case, I have a base drawable class (DGDrawable) that exposes a collection of child drawables.  I have a drawable sub-class (called DGNode) that adds a collection of DGPort objects (another DGDrawable sub-class).  DGNodes have special additional functionality associated with their child ports, but all the base class functionality of DGDrawable with respect to their children still applies.  DGNodes also repeat this pattern with other types of DGDrawable children, but for this example, I’ll just focus on the ports collection.

So what I’d like to be able do is have DGNode instances observe their port collection and edit the membership of their children collection to enjoy all the default DGDrawable behavior vis a vis child DGDrawables.

So for example, in the DGNode initializer, it registers to observe itself:

[self addObserver:self
       forKeyPath:@"ports"
          options:(NSKeyValueObservingOptionNew | 
                   NSKeyValueObservingOptionOld)
          context:nil];

And in it’s observer method, it edits it’s children collection to reflect changes to the ports collection:

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context
{
  int changeKind = [[change objectForKey:
    NSKeyValueChangeKindKey] intValue];
  if([keyPath isEqualToString:@"ports"])
  {
    if(changeKind == NSKeyValueChangeSetting ||
      changeKind == NSKeyValueChangeRemoval ||
      changeKind == NSKeyValueChangeReplacement)
    {
      NSMutableArray* children = 
        [self mutableArrayValueForKey:@"children"];
      for(DGPort* port in 
        [change objectForKey:NSKeyValueChangeOldKey])
      {
        [children removeObject:port];
        [port setNode:nil];
      }
    }
    if(changeKind == NSKeyValueChangeSetting ||
      changeKind == NSKeyValueChangeInsertion ||
      changeKind == NSKeyValueChangeReplacement)
    {
      NSMutableArray* children = 
        [self mutableArrayValueForKey:@"children"];
      for(DGPort* port in 
        [change objectForKey:NSKeyValueChangeOldKey])
      {
        [port setNode:self];
        [children addObject:port];
      }
    }
  }
}

Now, let’s say that another object external to the DGNode wants to use or observe the ports collection.  The addition of a port into the children collection is not guaranteed to happen with respect to when the external observer is notified (even though the DGNode registered it’s observation “first”). So in effect, the outside observer is told about changes to the DGNode when it’s in an “intermediate” state (i.e. the ports have been updated, but not the children collection).

In the context of a larger set of dependent connections and data binding, forgetting that there is no guarantee about the lack of order can make for some real fun debugging!

So my lesson learned for the day: architect order dependency out of KVO (and therefore data binding) from the get go to avoid having to continually prune away subtle ordering bugs .

Ahh, good times!

Published in: on May 11, 2009 at 5:45 pm  Comments (3)  
Tags: , ,

Core Data Rough Riding

Over the years, I’ve written a few different data models.  Some of them were even (gasp) documented!  Taking the time to nail the data model stack early on in app development has really helped with overall development efficiency and the ability to roll with the punches.  The more recent hand implemented data model stacks evolved to have some common features:

  • Data driven schema definitions
  • Some form of relational data representation
  • Files are first class entities
  • Ability to perform incremental loads  / be made partially resident
  • The ability to represent  inter-file entity references
  • Support for Undo / redo support
  • Support for Change tracking / change management
  • XML file format

Moving from the .Net world to Cocoa the obvious data model stack choice was Core Data.  Super promising and drool worth feature list!

  • Data driven schema definitions
    • Yup, can do.
  • Some form of relational data representation
    • Yup, can do.
  • Files are first class entities
    • Nope, you have to roll your own file referencing, but no biggie.
  • Ability to perform incremental loads  / be made partially resident
    • As long as you use SQLite as your backing store, but that’s cool.
  • The ability to represent  inter-file entity references
    • Nope, you have to roll your own, but no biggie.
  • Support for Undo / redo support
    • Yup, can do (or at least so I thought).
  • Support for Change tracking / change management
    • Yup, can do with KVC/KVO (or at least so I thought)
  • XML file format
    • Not if you want incremental load / save, but SQLite is hand debuggable enough.

Learning curve aside, the happy turned to sad as I started running into what turned out to be pretty common problems with Core Data’s support for undo.  Cocoa has a pretty slick undo paradigm.  Not exactly gang of four, but pretty cool.  The problem comes with the way Core Data interacts with it.  After a few days of spelunking and pain, I built enough vocabulary to ask Google the right questions, and the answers were not promising.

Take this blog post by Will Shipley (the Delicious Library guy):

“It’s pretty obvious I should be managing my OWN undoManager, turn off the one in CoreData, and just use CoreData for what it is EXTREMELY good at, which is minimal change tracking and fetching and storing data VERY VERY quickly.”

And then this other blog post by Mike Abdullah:

“Turning off undo registration doesn’t remove your changes from this system, it just stops the undo manager hearing about them. The change is still undone the moment the user wants to go back to a point before you made the change.”

“Sadly I don’t have a complete solution yet, but continue to ponder it. Do you have an idea? Get in touch, I’d love to hear from you.”

The kinds of problems I ran into were having Core Data KVO notify me in a redo that a relationship was being reconnected, but a query on the NSManagedObject in question would not yet be populated with any fields that I could use to index / sync with my controller or view representation.  Trying to force Core Data to sync with the undo system in bite sized chunks (i.e. subscribing to NSUndoManager notifications to hear about begin/end undo groups and calling NSManagedObjectContext’s processPendingChanges) to guarantee ordering doens’t work reliably (i.e. that insert object->set value->add gets undone in reverse order, and then redone in forward order).

Digging in further, CocoaDev mailing lists posts from purported Apple engineering dudes seem to indicate really isn’t much guarantee that Core Data will fire off KVO in undo/redo in rational orderings.  The problem is related to what Mike Abdullah describes in his blog post above: that Core Data implements undo / redo like commits and rollbacks to an SVN repository. Reading a few other blog posts like Will’s regarding spending years fighting Core Data’s undo system, I opted to turn it off and register my operations with NSUndoManager manually.  Unfortunately, my first attempt failed miserably.

My first approach was to capture the insertions, property changes, set additions/removals and deletions in the NSUndoManager.  A promising method on NSManagedObjectContext “insertObject” seemed like it would happily reverse “deleteObject”.  Unfortunately, instrumenting the save process and inspecting the NSManagedObjectContext’s pending insertions, deletions and registered objects proves this to be false.  Some more Cocoa Dev posts seem to confirm that while this will work with an XML backed persistent store, it won’t work with an SQLite backed store.  Without the ability to reverse an insert without recreating a new NSManagedObject, the tactic of capturing subsequent property changes and set additions/removals was mooted.  Time for my second approach.

My second approach was still to capture insertions, property changes, set additions/removals and deletions in the NSUndoManager, but using a primary key on each NSManagedObject rather than depending on the NSManagedObject to remain constant.  In this case the primary key is a string representation of a UUID (hey, what can I say, I’m an ex-Microsoft programmer).  Now, each operation in the undo/redo queue incurs a fetch request to find the NSManagedObject it needs to operate on.  Sucesss!  This method (while not the most performant undo/redo in the world) works reliably.

The next problem I ran into was saving.  Seems simple enough, but when loading a document, editing, saving, editing and saving a second time, Core Data deadlocks.  WTF?  Again, Google had a not very promosing (albiet not fatal) answer for me in the way of a post from Apple dude Ben Trumbell:

“There’s a known issue on the current Leopard using NSPersistentDocument with an SQLite store under Garbage Collection. Change any one of the 3 pieces in that configuration and things will work fine. We will be addressing the issue.”

Sweet, and that was from 2007.  Well, there is no freaking way I’m not going back to unmanaged programming, and the features offered by SQLite are more than half the reason I’m interested in Core Data, so don’t let the door hit you on the way out NSPersistentDocument!

On the bright side after all this spelunking, it was only about a ten minute task to create a (minimalistic) alternative implementation of NSPersistentDocument supporting Save, Save As, etc.

Published in: on May 7, 2009 at 2:34 am  Comments (1)  
Tags: , ,
Follow

Get every new post delivered to your Inbox.