Quantcast

A Joyous Crash in removeObserver:forKeyPath: / _NSKeyValueObservationInfoCreateByRemoving

 Images Frustration Today I had the joy of trying to figure out a tough crashing bug somewhere deep inside a Cocoa / Core Data / KVC / KVO application. In case anyone else is running into this crash, it’s not your fault:

Ah, the infamous _NSKeyValueObservationInfoCreateByRemoving crash bug.
That’s shown up with a number of triggers, and is definitely not
reproducible, nor is your code at fault. I filed a bug on it, and Jim
Correia (who often posts on this list) has sent in a reproducible case.

If you can figure out the interface item or binding that’s triggering it,
you may be able to work around it. In my case, I was able to have an object
traverse a relationship for me, instead of binding through the relationship,
and that stopped the crashing.

I was able to avoid this crash by overriding removeObserver:forKeyPath: to do nothing (especially not call NSObject’s implementation, which was doing the crashing).

I’m also getting a crash in -[NSOutlineView _sendDelegateWillDisplayCell:forColumn:row:] which I don’t understand. I’ve turned off all my NSOutlineView customizations….maybe I’m calling reloadData too often. If anyone has ideas, I’m all ears.

Link to a cocoa-dev message I wish I had seen about six hours ago

One Response to “A Joyous Crash in removeObserver:forKeyPath: / _NSKeyValueObservationInfoCreateByRemoving”

  1. killerdemouches
    June 4th, 2007 | 5:29 am

    It may interess someone.

    I add some problem working arround with this bug, so i decided to fix this issue of NSObject by myself:

    // NSObjectKVOCrashFixer.h

    1. import

    @interface NSObjectKVOCrashFixer : NSObject {

    }

    @end

    // NSObjectKVOCrashFixer.m

    1. import “NSObjectKVOCrashFixer.h”

    @implementation NSObjectKVOCrashFixer
    - (void)_removeObserver:(NSObject *)anObserver forProperty:(id)property
    {
    if([self observationInfo]!=NULL)
    [super _removeObserver:anObserver forProperty:property];
    else
    NSLog(@”Fixed an Apple crash!”);
    }
    @end

    and

    // main.m

    1. import
    2. import “NSObjectKVOCrashFixer.h”

    int main(int argc, char *argv[])
    {
    [NSObjectKVOCrashFixer poseAsClass:[NSObject class]];
    return NSApplicationMain(argc, (const char **) argv);
    }

    I know this is dirty. But it works and it seems necessary for me until apple check by themselves if value==NULL before doing a CFRelease…

Leave a reply