Search code examples
cocoamacoscore-datanibnsarraycontroller

NSArrayController initialization


I am having trouble getting an core-data backed NSArrayController to work properly in my code. Below is my code:

pageArrayController = [[NSArrayController alloc] initWithContent:nil];
    [pageArrayController setManagedObjectContext:[self managedObjectContext]];
    [pageArrayController setEntityName:@"Page"];
    [pageArrayController setAvoidsEmptySelection:YES];
    [pageArrayController setPreservesSelection:YES];
    [pageArrayController setSelectsInsertedObjects:YES];
    [pageArrayController setClearsFilterPredicateOnInsertion:YES];
    [pageArrayController setEditable:YES];
    [pageArrayController setAutomaticallyPreparesContent:YES];
    [pageArrayController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES]]];
    BOOL result = [pageArrayController setSelectionIndex:0];

When I attempt to call setSelectionIndex:, it returns YES, indicating that the selection has been successfully changed. However, any subsequent getSelectionIndex calls to the pageArrayController object returns NSNotFound.

What I don't understand is that if I put the NSArrayController into a NIB, and allow the NIB file to perform the initialization (with all of the same attributes in Interface Builder), the NSArrayController works correctly.

Why is there a difference in behavior? Does the NIB file initialize these types of objects in a special way? Is my initialization of the NSArrayController incorrect?

Any help is appreciated. Thanks.


Solution

  • Yes, nibs do initialize objects in a special way and sometimes it can be hard to figure out how to replicate that. I struggled with this too and finally found the answer in Apple's Core Data Programming Guide >> Core Data and Cooca Bindings >> Automatically Prepares Content Flag (thanks to Dave Fernandes on the Cocoa Dev list). The answer is that if you initialize an arraycontroller with nil content, you need to perform a fetch as well.

    BOOL result;
    NSArrayController *pageArrayController = [[NSArrayController alloc] initWithContent:nil];
    [pageArrayController setManagedObjectContext:[self managedObjectContext]];
    [pageArrayController setEntityName:@"Page"];
    NSError *error;
    if ([pageArrayController fetchWithRequest:nil merge:YES error:&error] == NO) 
         result = NO;
    else
    {
         //do all that other pageArrayController configuration stuff
         result = [pageArrayController setSelectionIndex:0];
    }
    

    BTW, [NSSortDescriptor sortDescriptorWithKey:@"index" ascending:YES]] raises a warning.