views:

451

answers:

2

Hi, I have an NSMutableArray and I load my tableview from it. Now I have a Button in the UI which kinda lets the user refresh the data that goes into the array multiple times. And everytime there is new data in the Array I want to refresh the tableView. Just doing [tableView reloadData] after updating the array seems to bring up the beachball. ANy ideas on what would be a good way to achieve this ?

Also I have been taking a look at bindings as a way to implement my NSTableView from an array but all the examples shown online use bindings when they want to add data to their tables ? Can anyone point me on how I could load a array with data into tableView using Bindings ?

Sorry if the questions are noobie ones, I am willing to read if someone can point me to the right data. Thanks :) ( I am not looking for a shortcut, just trying to get some learned advice from experienced folks on how to approach these things )

-(IBAction)refreshList:(id)sender
{
//setup array here and sort the array based on one column. This column has 
  identifier 'col1' and it works as expected


[aTable reloadData];
  } 

- (int) numberOfRowsInTableView:(NSTableView *)aTable
{ // return count of array
 }

- (id)tableView:(NSTableView *)aTable objectValueForTableColumn: (NSTableColumn *)          
tableColumn row:(int)row
 { 
 //set up arrays here to load data in each column


 }
- (void)tableView:(NSTableView *)aTableView sortDescriptorsDidChange:(NSArray   
 *)oldDescriptors
 {
 //sort here when column headers are clicked
 } 

 -(IBAction)autorefresh:(id)sender
   {

 // Here i am trying to reload the array and refresh the tableView. I want to       
  constantly keep refreshing the array and loading the tableView here. The array does 
  get   refreshed but I am having trouble loading the tableView.


  for ( int i =0; i<=2;i++)
  { 
     // reload the array with data first.
  [aTable reloadData];
    i = 1;

  } 
+1  A: 

If -reloadData is causing a beachball it almost certainly means there is something wrong with your controller's implementation of the NSTableDataSource protocol. You need to work out why this is happening and fix it. If you post your table data source code then maybe we can help you work out why this is.

I highly recommend you become familiar with the "standard" NSTableView datasource and delegate methods before even looking at bindings. Cocoa Bindings is a relatively advanced topic and it very much sounds like you need more basic Cocoa experience before you move on to bindings.

That said, this page has a comprehensive set of Cocoa bindings examples:

http://homepage.mac.com/mmalc/CocoaExamples/controllers.html

Update since you posted your code:

I have to assume that you've deliberately left out the implementation of the datasource methods in the code above, since the code as you posted it won't compile without warnings.

Your autorefresh method is an infinite loop. That would explain the beachballing. You are setting i to 1 on each iteration of the loop, which means the end condition is never being reached.

However, using a for loop like this is a terrible, terrible way to refresh a table view and will block the main thread. If you need to repeatedly update the table view on a regular basis, use an NSTimer that is called at a specified interval.

Rob Keniger
thanks irsk. I will definitely do some more reading. I added the code above. Any ideas ?
califguy
oops, stupid mistake. Got it. I implemented NSTimer and it works as expected. Thanks a lot.
califguy
A: 

With that code (and especially your very novel "while true" loop), you get a beach-ball because you never get back to the man run-loop. To fix use code like this after setting up the NSTableView, and it will run every 1.0 seconds

NSTimer* timer = [NSTimer timerWithTimeInterval:1.0
                                         target:[NSApp delegate]
                                       selector:@selector(myReloadData:)
                                       userInfo:nil
                                        repeats:YES];

[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];  

Then create myReloadData in your app delegate

- (void)reloadMyData:(NSTimer*)ntp
{
  // reload the array with data first.
  [aTable reloadData];
}
Erik Elmgren