Search code examples
objective-ccore-datansmanagedobjectcontextnsarraycontroller

Using NSArrayController without Core Data


I'm using Core Data in my OS X application where I have some TableViews bound to NSArrayControllers. The problem I'm having is when I'm trying to populate a tableview in a sheet using an array controller where I don't want the contents to persist.

Here's how the app hangs together;

Window 1 - Shows a list of users in a table view and allows adding and removing users. Contents persist via Core Data bindings.

Window 2 - Shows a list of groups in a table view. A second table view shows a list of users that belong to the selected group. Contents persist via Core Data bindings. An 'add users' button invokes a sheet for adding users to the group.

Add Users sheet - This sheet shows a table view of users that are not already members of the selected group. Pressing the close button on the sheet adds the selected users to the selected group.

Ok, so the problem I'm having is with the array controller for the Add Users sheet. When I invoke the sheet I iterate through all users and add any to the array controller if they don't already exists in the group. When I close the sheet I try to clear down the array controller using removeObject: but this causes a "can't use this method with a ModelObjectContect."

Why do I need a MOC to remove items from the array controller? It's only for display purposes so I don't need it to persist. If I set the array controllers MOC to that of my app delegate, it physically deletes the users, which I obviously don't want. I just want to remove them from the table view of the sheet.

I thought the answer might be to create another MOC to use as a scratch-pad and not tie it to a persistent store, however this just gave me a different error when using removeObject:, something along the lines of "can't remove objects that exists in another MOC."

Why am I allowed to add object to an array controller but not remove them? In cases where you don't actually want the items physically removed are you supposed to access the the underlying "content", e.g. [arraycontroller content]? I've played with this but get strange display results as it seem to be playing with the array controller's content behind it's back. If I do this, is there a way to tell the array controller "by the way, I've been tinkering with you're content and you may need to get yourself together"?

It looks to me like you shouldn't be using array controllers without Core Data, but there is numerous comments in the documentation that suggests that it works with and without core data.


Solution

  • Yes, you can use an array controller without a Core Data Managed Object Context. But as you're storing NSManagedObject instances inside it, I think it tries to mark them for deletion when you removed them.

    If you work with managed objects and don't want the contents of the array controller to be deleted on removal, you have to bind the array controller's content to another object's property with Cocoa Bindings.

    But there is a simpler solution. I suggest you to set the managed object context of the array controller to your main MOC and use a predicate to filter its content.

    [arrayController setPredicate:[NSPredicate predicateWithFormat:@"NONE groups == %@", group]];
    

    Thus, there is not need to add or remove users from the array controller as all users that are already in the group will be hidden.