NSDictionary objects not appearing in NSTableView

Discussion in 'Mac Programming' started by Insomnica, Mar 6, 2011.

  1. Insomnica macrumors newbie

    Joined:
    Oct 9, 2010
    Location:
    Manchester, UK
    #1
    Hey MR,

    I've been puzzling myself over this problem for a month or two now, and after researching the problem on Google and other programming QA sites, I haven't managed to find the error.

    So my problem goes like so:
    I have a WindowController and ArrayController, both NSObjects. An NSTableView, with each of it's three columns bound to Key Paths and hooked up to the ArrayController.

    My program will use an external HTTP stream, and generate an NSMutableArray of NSMutableDictionary objects, which are then passed to the ArrayController.

    I can accurately generate the Dictionaries, and compile the Array of said dictionaries. The problem lies in why I cannot get it to visually display on the form.

    I'm literally at last-chance saloon with this error, and if I can save the project, i'd be eternally appreciative!
    I've uploaded the project to my webspace if anyone fancies a peek, or I can post some of the code when I know what will help. :)

    Thanks,
    Matt.
     
  2. McGordon, Mar 6, 2011
    Last edited: Mar 6, 2011

    McGordon macrumors member

    Joined:
    Dec 28, 2010
    Location:
    Scotland
    #2
    I've had a quick look and your code is throwing an index beyond bounds exception, which is caught and logged in your @try-@catch in TrackRequest: (NSString *)srcString method of MusicFunctions.m.

    Code:
    2011-03-06 12:25:55.585 Downstream[714:a0b] The ERROR: *** -[NSCFArray objectAtIndex:]: index (1159) beyond bounds (1159)
    
    Your i<arrayCount looks ok, but in the loop you post-increment i in a while loop which will easily put i beyond the bounds of the array.

    Code:
       @try {
          
          //While we've got lines to read...
          [COLOR="green"]for(int i=0; i<arrayCount; i++)[/COLOR]
          {
             htmlLine = [temp_array objectAtIndex:i];
             if(htmlLine == NULL) { break; }
             
             if([htmlLine rangeOfString:@"<div class=\"detail\">"].location != NSNotFound)
             {
                while(!allDataAcquired)
                {
                   htmlLine = [temp_array objectAtIndex:[COLOR="red"]i++[/COLOR]];
                   NSString *trackTitle, *trackArtist, *trackAlbum, *trackLink;
                   
                   if ([htmlLine rangeOfString:@"Title:"].location != NSNotFound)
                   {
                      htmlLine = [temp_array objectAtIndex:[COLOR="Red"]i++[/COLOR]];
                      
                      //Filter excess HTML from the Title Line.
                      trackTitle = [self stripExcessHTML:htmlLine:NULL];
                   }
                   
    
    
    I've not checked anything else, just telling you the first thing I saw.


    Edit: The above is not the problem, its just your crazy loop that only stops when it throws an exception and catches it!
     
  3. Insomnica thread starter macrumors newbie

    Joined:
    Oct 9, 2010
    Location:
    Manchester, UK
    #3
    Thanks for the helpful response, McGordon!

    I actually refactored that entire method, it was completely inefficient and used a couple of CPU cycles that would be lovely to free up.
    Now will hit the end of the for loop, as planned. :)

    Still at a loss as to why it's not appearing, the Reference Bindings look good and the NSArray<NSMutableDictionary> looks good when their descriptions are printed to the console.
    I wish I were getting an error, or even bad memory access. I can fix them.
    Here, i'm drawing a blank...
     
  4. McGordon macrumors member

    Joined:
    Dec 28, 2010
    Location:
    Scotland
    #4
    I've got it to display the content in the NSTableView. I'm learning Cocoa too, so this might not be the best way to go about this, but here goes. I think the problem is that you're not doing things in a key-value-observing compliant manner so that the controller is informed of the changes.

    Instead of adding the new dictionaries to your array and hope that NSTableView reads it, add the new content to the NSArrayController and it'll take care of everything. So add them to arrayTracks (your NSArrayController) instead of tracksArray (your NSMutableArray).

    Change this in WindowController.m:
    Code:
    - (IBAction)searchAction:(id)sender {
       
       NSString* fixedString = NULL;
       fixedString = [[sender stringValue] stringByReplacingOccurrencesOfString:@" " withString:@"-"];
       
        NSMutableArray *array = [exMusicFunction TrackRequest:fixedString];
       
       for(id dc in array)
       {
          [tracksArray addObject:dc];
       }
       
       [tblTrackView reloadData];
       
    }
    
    
    to this:
    Code:
    - (IBAction)searchAction:(id)sender {
       
       NSString* fixedString = NULL;
       fixedString = [[sender stringValue] stringByReplacingOccurrencesOfString:@" " withString:@"-"];
       
        NSMutableArray *array = [exMusicFunction TrackRequest:fixedString];
       
       [arrayTracks addObjects:array];
    }
    
    I also changed the ArrayController's bindings from selection.tracksArray to just tracksArray with no Model Key Path.

    Controller Key: tracksArray
    Model Key Path:
    Value Transformer:

    Now it works!
     
  5. Insomnica thread starter macrumors newbie

    Joined:
    Oct 9, 2010
    Location:
    Manchester, UK
    #5
    McGordon, thank you so much!
    You're a gentleman, and a scholar.

    Got it cracked on my end now, just some cosmetic issues before I go wrestling with AudioToolbox framework. :p

    Thank you so much for all your help with this thread!

    Matt.
     

Share This Page