PDA

View Full Version : Call reloadData for NSTableView from AppDelegate




AdrianK
Aug 7, 2012, 11:37 AM
I have an NSTableView set up in my application and I want to be able to call "reloadData" from AppDelegate, since that's where I'm modifying the data source array (stored in a singleton class).

Can I get a pointer to the instance of the NSTableView's controller so I can send a message to that instance? I may be barking up the wrong tree but that's all I can think of. I'm not sure how to get the pointer, since I didn't create the instance of the controller, it's wired up to the table in Xcode...

Thanks.



GorillaPaws
Aug 8, 2012, 07:06 AM
It sounds like your class structure is a little wonky. Your data source should be in a controller class (how did you manage to implement NSTableView's data source protocol in NSArray (as a category)? Your NSArray should be your model class, your appDelegate (which is a controller class) should be the data source that is instanciated in the .xib file and you can wire up references to it via interface builder.

What class is trying to call reload data? I get the feeling you haven't fully described your object graph to us.

AdrianK
Aug 11, 2012, 06:45 AM
Thanks for the response :)

Sorry, the explanation I gave in the OP wasn't very clear, I'll try again.
Your data source should be in a controller class (how did you manage to implement NSTableView's data source protocol in NSArray (as a category)?

I have a controller for the table view, data source is wired up and protocols implemented. Instead of storing the array in the controller, it's in a singleton class so I can add/remove objects from any other class (this works if I add some test objects to array in -(id)init).

I'm adding objects to the array from AppDelegate, but the table doesn't update to reflect the change.

I'm trying to add to the array from AppDelegate because I want to use this method - (BOOL)application:(NSApplication*)app openFile:(NSString*)file; to detect when files are dropped on the dock icon. I get a warning that the app can't open files if I move this to the table view controller, not that it should be there anyway. Is it possible to tell to the controller class to reloadData for the NSTableView?

chown33
Aug 11, 2012, 01:32 PM
I have a controller for the table view, data source is wired up and protocols implemented. Instead of storing the array in the controller, it's in a singleton class so I can add/remove objects from any other class (this works if I add some test objects to array in -(id)init).

I'm adding objects to the array from AppDelegate, but the table doesn't update to reflect the change.

Post your code.

You should be adding objects to your data-model class (i.e. your data source), not directly an underlying array of the model. I can't tell from the description if the array is your entire model, or just one part of the model.

Your model class should be written so that when objects are added to it (or removed) by external entities, the model tells the controller that something changed. The controller is then responsible for telling the view to refresh.

That's just one possible design.

A different one is to make only the controller object externally visible (singleton or whatever), and give it methods that do two things: add/remove object from model object, tell view to update. Then your external objects all communicate directly with the controller object, never directly with the model object. Since all adds and removes go through the controller, it can always tell both the model and the view what to do and when.

There are plusses and minuses of each design. One isn't consistently better than the other. For example, if the overall design is one in which the model object is more-or-less self-updating, such as a model that periodically scans a folder or looks for changes in something, then the model-tells-controller design may be preferred. However, that responsibility can also be assigned to the controller object, which performs the periodic part of the task, and the model object is then simpler, but less independent. A lot of factors go into where to draw the line, such as what other classes are already being used, ease or difficulty of changing a particular model or controller class, and so on.

If you don't have a written list of responsibilities for each of the controller and model classes, writing one down might be a good way to see if you have a clear separation of responsibilities. Simply making the list can often show inconsistencies in who is responsible for things like updated data.


I'm trying to add to the array from AppDelegate because I want to use this method - (BOOL)application:(NSApplication*)app openFile:(NSString*)file; to detect when files are dropped on the dock icon. I get a warning that the app can't open files if I move this to the table view controller, not that it should be there anyway. Is it possible to tell to the controller class to reloadData for the NSTableView?

Yes: simply switch the design to one where the controller is the visible object (singleton), and you only communicate directly with the controller. All changes (adds or removes) go directly to the controller object, and only indirectly to the model object. Passing the data to the model object and triggering an update becomes the controller's responsibility, not the responsibility of your AppDelegate.

You might want to review the Cocoa MVC description.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaFundamentals/