PDA

View Full Version : Debugging help?




kwarren
Feb 18, 2009, 05:05 AM
Hi,

So, I have a tab bar-based app that is essentially a specialized RSS reader (pulling from preset feeds).

Anyway, I recently decided to incorporate a UISearchBar into one of the app's tabs. I downloaded the source from Apple's TableSearch example, mined it for what I (believe) I need, changed the array names (could this be complicated by the fact that I'm using a mutable array?), and connected the search bar properly in Interface Builder. Everything loads up fine, and the app works just as it should: I can do everything as normal, but when I navigate to the tab with the search--tab X--click within the search bar, and attempt to select a key (say, A), the app freezes immediately, and Xcode tells me that the the simulator is "Terminating due to uncaught exception". How might I fix this? My app certainly didn't do this before.

Here is all of the code relevant to the search bar: @synthesize filteredListContent, savedContent, stories, newsTable, mySearchBar;

- (void)awakeFromNib
{


// create our filtered list that will be the data source of our table, start its content from the master "stories"
filteredListContent = [[NSMutableArray alloc] initWithCapacity: [stories count]];
[filteredListContent addObjectsFromArray: stories];

// this stored the current list in case the user cancels the filtering
savedContent = [[NSMutableArray alloc] initWithCapacity: [stories count]];

// don't get in the way of user typing
mySearchBar.autocorrectionType = UITextAutocorrectionTypeNo;
mySearchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
mySearchBar.showsCancelButton = NO;
}

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
// only show the status bar's cancel button while in edit mode
mySearchBar.showsCancelButton = YES;

// flush and save the current list content in case the user cancels the search later
[savedContent removeAllObjects];
[savedContent addObjectsFromArray: filteredListContent];
}

- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
mySearchBar.showsCancelButton = NO;
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
[filteredListContent removeAllObjects]; // clear the filtered array first

// search the table content for cell titles that match "searchText"
// if found add to the mutable array and force the table to reload
//
NSString *cellTitle;
for (cellTitle in stories)
{
NSComparisonResult result = [cellTitle compare:searchText options:NSCaseInsensitiveSearch
range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame)
{
[filteredListContent addObject:cellTitle];
}
}

[newsTable reloadData];
}

// called when cancel button pressed
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
// if a valid search was entered but the user wanted to cancel, bring back the saved list content
if (searchBar.text.length > 0)
{
[filteredListContent removeAllObjects];
[filteredListContent addObjectsFromArray: savedContent];
}

[newsTable reloadData];

[searchBar resignFirstResponder];
searchBar.text = @"";

}

// called when Search (in our case "Done") button pressed
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}

- (void)dealloc {

[newsTable release];
[mySearchBar release];

[stories release];
[filteredListContent release];
[savedContent release];

[super dealloc];
}


Thanks in advance! I have no idea how to fix this since I'm kind of a noob.

Here's what the debugger says:



jnic
Feb 18, 2009, 05:10 AM
What output are you seeing on the console?

kwarren
Feb 18, 2009, 05:14 AM
What output are you seeing on the console?

It runs as normal (pulling stories and such) until....
[Session started at 2009-02-18 03:12:28 -0800.]
2009-02-18 03:12:28.599 WH[83213:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFDictionary compare:options:range:]: unrecognized selector sent to instance 0x5ddaa0'
2009-02-18 03:12:28.600 WH[83213:20b] Stack: (
2445853003,
2503790139,
2445882186,
2445875532,
2445875730,
16097,
818077817,
816518502,
816517018,
816556437,
816597142,
2496995802,
2445228730,
2445229459,
2496984128,
2445875837,
2445874280,
850484431,
850484628,
2348511,
846469279,
846442552,
846438529,
846436504,
846435605,
845449443,
845447891,
845446943,
846435135,
846434889,
2345022,
850378372,
2411107,
2563520,
817597038,
817291713,
817484569,
817494424,
817508817,
816216335,
816148471,
816144856,
827735530,
827745292,
2445354517,
2445356280,
827737600,
827737797,
816114840,
816160916,
10648,
10502

Again, I have no idea how to fix this, and search is kind of integral to my app, so if there's anyway anyone can help, I'd be so grateful!

Thanks again,

jnic
Feb 18, 2009, 05:20 AM
2009-02-18 03:12:28.599 WH[83213:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFDictionary compare: options: range:]: unrecognized selector sent to instance 0x5ddaa0'

So this is the line it's choking on:

NSComparisonResult result = [cellTitle compare:searchText options:NSCaseInsensitiveSearch range:NSMakeRange(0, [searchText length])];

What type is cellTitle meant to be?

kwarren
Feb 18, 2009, 05:26 AM
What type is cellTitle meant to be?

I don't actually know, but it comes from the TableSearch example, not my code. I must have totally glossed over that when I was mining Apple's source. How might I go about fixing that?

Thanks for all of the help, jnic!

jnic
Feb 18, 2009, 05:41 AM
It's declared as an NSString but for some reason is being treated as an NSCFDictionary, and I'm pretty pure neither inherits from the other.

Is it being shadowed anywhere? (i.e. do you declare another variable also called cellTitle anywhere in your code?)

Also, are you getting any compiler warnings after you clean all and rebuild? Does it work if you add a cast?

[cellTitle compare:...]

to

[(NSString *)cellTitle compare:...]

?

kwarren
Feb 18, 2009, 05:58 AM
jnic, I just PM'd you so that maybe you can continue leading an idiot through this process. ;)

jnic
Feb 18, 2009, 06:31 AM
OK, found the problem (I'll post it here so it might be useful for others in future).

cellTitle is in fact an NSMutableDictionary (hence the console complaint) and was being cast (unsuccessfully) back to an NSString, rather than extracting the element from the dictionary which was the desired NSString.

The fix is to replace:

NSString *cellTitle;

[...]

NSComparisonResult result = [cellTitle ...


with

NSMutableDictionary *cellTitle;

[...]

NSComparisonResult result = [[cellTitle objectForKey:@"title"] ...

:)

kwarren
Feb 18, 2009, 06:39 AM
My God! jnic, I think I love you. Thank you so much!! You just saved me from nearly scrapping the entire project!