debugging hard-to-locate error in NSApplication delegate

  • Hi,

    Does anyone have working code that shows an application delegate in a
    core data document-based app?  I'm trying to intercept
    applicationShouldOpenUntitledFile: in order to open the last-saved
    document.  I have code that works, but it causes this error:

    *** -[NSCFArray insertObject:atIndex:]: attempt to insert nil

    some time between the setting of the delegate, which I did by inserting
    this object into the nib and setting the delegate programmatically.
    linking from IB did not properly set the delegate (init and
    applicationDidFinishLaunching: were called, but
    applicationShouldOpenUntitledFile: was never called):

    @implementation GreenwoodAppDelegate

    - (void) init
    {
        [super init];
        applicationHasStarted = NO;
        if (![[NSApplication sharedApplication] delegate]) {
            [[NSApplication sharedApplication] setDelegate:self];
        }
    }

    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
        applicationHasStarted = YES;
    }

    - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
    {
        // On startup, when asked to open an untitled file, open the last opened
        // file instead
        if (!applicationHasStarted)
        {
            // Get the recent documents
            NSDocumentController *controller =
            [NSDocumentController sharedDocumentController];
            NSArray *documents = [controller recentDocumentURLs];

            // If there is a recent document, try to open it.
            if ([documents count] > 0)
            {
                NSError *error = nil;
                [controller
                openDocumentWithContentsOfURL:[documents objectAtIndex:0]
                display:YES error:&error];

                // If there was no error, then prevent untitled from appearing.
                if (error == nil)
                {
                    return NO;
                }
            }
        }

        return YES;
    }
    @end

    I borrowed the code in applicationShouldOpenUntitledFile: from a helpful
    blog entry, can't remember where.

    Thanks,
    Greg
  • On Mon, Jan 12, 2009 at 11:11 AM, Greg Beaver <greg...> wrote:
    > Hi,
    >
    > Does anyone have working code that shows an application delegate in a
    > core data document-based app?  I'm trying to intercept
    > applicationShouldOpenUntitledFile: in order to open the last-saved
    > document.  I have code that works, but it causes this error:
    >
    > *** -[NSCFArray insertObject:atIndex:]: attempt to insert nil

    First thing you need to do is find out where this error is coming
    from. Without that information, the problem is far too difficult. See
    "Breaking on Exceptions" on this page:

    http://www.cocoadev.com/index.pl?DebuggingTechniques

    Mike
  • Thanks for posting that link on breaking on exceptions...I'd been looking for some way to do that.  I wish Xcode would simply stop on an offending line [in my code, not the library behind] instead of making me hunt it down...that's one thing I do like about programming using MS' tools...

    Peace, Love, and Light,

    /s/ Jon C. Munson II

    -----Original Message-----
    From: cocoa-dev-bounces+jmunson=<his.com...> [mailto:cocoa-dev-bounces+jmunson=<his.com...>] On Behalf Of Michael Ash
    Sent: Monday, January 12, 2009 11:24 AM
    To: Cocoa Developers
    Subject: Re: debugging hard-to-locate error in NSApplication delegate

    On Mon, Jan 12, 2009 at 11:11 AM, Greg Beaver <greg...> wrote:
    > Hi,
    >
    > Does anyone have working code that shows an application delegate in a
    > core data document-based app?  I'm trying to intercept
    > applicationShouldOpenUntitledFile: in order to open the last-saved
    > document.  I have code that works, but it causes this error:
    >
    > *** -[NSCFArray insertObject:atIndex:]: attempt to insert nil

    First thing you need to do is find out where this error is coming
    from. Without that information, the problem is far too difficult. See
    "Breaking on Exceptions" on this page:

    http://www.cocoadev.com/index.pl?DebuggingTechniques

    Mike
  • On Jan 12, 2009, at 08:11, Greg Beaver wrote:

    > Does anyone have working code that shows an application delegate in a
    > core data document-based app?  I'm trying to intercept
    > applicationShouldOpenUntitledFile: in order to open the last-saved
    > document.  I have code that works, but it causes this error:
    >
    > *** -[NSCFArray insertObject:atIndex:]: attempt to insert nil
    >
    > some time between the setting of the delegate, which I did by
    > inserting
    > this object into the nib and setting the delegate programmatically.
    > linking from IB did not properly set the delegate (init and
    > applicationDidFinishLaunching: were called, but
    > applicationShouldOpenUntitledFile: was never called):
    >
    > @implementation GreenwoodAppDelegate
    >
    > - (void) init
    > {
    > [super init];
    > applicationHasStarted = NO;
    > if (![[NSApplication sharedApplication] delegate]) {
    > [[NSApplication sharedApplication] setDelegate:self];
    > }
    > }

    This isn't going to work because your app delegate object is in your
    NIB file and is (re)created at startup by unarchiving. Therefore,
    'initWithCoder' will be called instead or 'init'.

    I think you'd be better off setting your application's delegate outlet
    to the app delegate object in your main NIB file after all, and then
    trying to work out why applicationShouldOpenUntitledFile: isn't
    behaving as expected.
  • Quincey Morris wrote:
    > On Jan 12, 2009, at 08:11, Greg Beaver wrote:
    >
    >> Does anyone have working code that shows an application delegate in a
    >> core data document-based app?  I'm trying to intercept
    >> applicationShouldOpenUntitledFile: in order to open the last-saved
    >> document.  I have code that works, but it causes this error:
    >>
    >> *** -[NSCFArray insertObject:atIndex:]: attempt to insert nil
    >>
    >> some time between the setting of the delegate, which I did by inserting
    >> this object into the nib and setting the delegate programmatically.
    >> linking from IB did not properly set the delegate (init and
    >> applicationDidFinishLaunching: were called, but
    >> applicationShouldOpenUntitledFile: was never called):
    >>
    >> @implementation GreenwoodAppDelegate
    >>
    >> - (void) init
    >> {
    >> [super init];
    >> applicationHasStarted = NO;
    >> if (![[NSApplication sharedApplication] delegate]) {
    >> [[NSApplication sharedApplication] setDelegate:self];
    >> }
    >> }
    >
    > This isn't going to work because your app delegate object is in your
    > NIB file and is (re)created at startup by unarchiving. Therefore,
    > 'initWithCoder' will be called instead or 'init'.
    >
    > I think you'd be better off setting your application's delegate outlet
    > to the app delegate object in your main NIB file after all, and then
    > trying to work out why applicationShouldOpenUntitledFile: isn't
    > behaving as expected.
    Hi,

    I figured out the problem from:

    http://www.cocoadev.com/index.pl?NSApplication

    At the bottom of the page, someone had a similar issue.  Turns out, I
    thought my Greenwood.xib was the main nib, instead of MainMenu.xib.
    Putting the app delegate in mainmenu.nib and linking in IB causes
    expected behavior, and removes the exception.

    Thanks for all of the help, that exception trick will be extremely
    useful, I run into "track the exception source" all the time, although
    usually it's much easier to debug.

    Thanks,
    Greg
  • On Jan 12, 2009, at 11:41 AM, Quincey Morris wrote:

    >> - (void) init
    >> {
    >> [super init];
    >> applicationHasStarted = NO;
    >> if (![[NSApplication sharedApplication] delegate]) {
    >> [[NSApplication sharedApplication] setDelegate:self];
    >> }
    >> }
    >
    > This isn't going to work because your app delegate object is in your
    > NIB file and is (re)created at startup by unarchiving. Therefore,
    > 'initWithCoder' will be called instead or 'init'.

    I don't think this is precisely true, particularly for regular objects
    (the plain blue cube). At least, none of mine behave this way. Of
    course, none of the objects I use in this way implement NSCoding, and
    maybe that matters. All other non-view objects do instantiate with
    initWithCoder:, as I understand, just not generic custom objects.

    Best,

    Keary Suska
    Esoteritech, Inc.
    "Demystifying technology for your home or business"
  • On Mon, Jan 12, 2009 at 1:41 PM, Quincey Morris
    <quinceymorris...> wrote:
    > This isn't going to work because your app delegate object is in your NIB
    > file and is (re)created at startup by unarchiving. Therefore,
    > 'initWithCoder' will be called instead or 'init'.

    Well actually no, the true picture is considerably more complex than
    that, and -init is correct.

    NSWindows get the full NSWindow initializer.

    Plain old NSViews (which are then often customized to a different
    subclass in the inspector) get -initWithFrame:.

    Other top-level nib objects get plain old -init.

    And everything else (pre-made views and controls off the palette) gets
    -initWithCoder:.

    I *think* that's the full list of what gets initialized how, but I may
    have missed a spot.

    Mike
  • On Jan 12, 2009, at 5:06 PM, Michael Ash wrote:

    > On Mon, Jan 12, 2009 at 1:41 PM, Quincey Morris
    > <quinceymorris...> wrote:
    >> This isn't going to work because your app delegate object is in
    >> your NIB
    >> file and is (re)created at startup by unarchiving. Therefore,
    >> 'initWithCoder' will be called instead or 'init'.
    >
    > Well actually no, the true picture is considerably more complex than
    > that, and -init is correct.
    > [...]
    > I *think* that's the full list of what gets initialized how, but I may
    > have missed a spot.
    >
    <http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/
    CocoaNibs/chapter_3_section_4.html
    >

    mmalc
  • On Jan 12, 2009, at 16:40, Keary Suska wrote:

    > I don't think this is precisely true, particularly for regular
    > objects (the plain blue cube). At least, none of mine behave this
    > way. Of course, none of the objects I use in this way implement
    > NSCoding, and maybe that matters. All other non-view objects do
    > instantiate with initWithCoder:, as I understand, just not generic
    > custom objects.

    Thanks for the correction (and to all who corrected me).

    Can I ask for half credit for suggesting a reason that might have half
    explained the OP's problem if it had been a half valid reason? Well,
    never mind.