So here is the deal, I am using FMDB SQLite Wrapper for my DB app. I know Cord Data is there but My database is really really huge and all I want to do is read it. No new records are going to be inserted / updated via iOS app. At one point in this app I am trying to pull records from DB which are name of player and thier Id based on searchTerm and searchPosition. searchTerm works perfectly fine. searchPosition query works in sqlite3 but not in iOS app. I don know where I am going wrong. Help me out. Code for both methods are as follows:
-(IBAction)searchTerm
{
searchTermValue=self.term.text;
self.fmdbUtils = [[[FMDBUtils alloc] initWithDatabase:#"Colts.sql"] autorelease];
FMDatabase *db = [self.fmdbUtils sharedDB];
FMResultSet *rs = nil;
NSString *AgentId = nil;
NSString *PlayerName = nil;
NSString *PlayerId = nil;
ScoutAppDelegate *appDelegate = (ScoutAppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.playerList = [[NSMutableArray alloc] init];
NSString * query = #"SELECT * FROM Player WHERE LENGTH (lastname)>0 AND LENGTH (firstname)>0 AND ( lastname LIKE '%' || ? || '%' OR firstname LIKE'%' || ? || '%' OR Height LIKE '%' || ? || '%' OR Weight LIKE '%' || ? || '%') ORDER BY lastname,firstname";
rs = [db executeQuery:query,searchTermValue,searchTermValue,searchTermValue,searchTermValue];
[query release];
while([rs next])
{
PlayerId = [rs stringForColumn:#"player_id"];
//NSString *PlayerName = [rs stringForColumn:#"Player Name"];
if ([rs stringForColumn:#"Player Name"]!= NULL)
{
PlayerName = [rs stringForColumn:#"Player Name"];
}
else
PlayerName=#"";
if ([rs stringForColumn:#"agent_id"]!= NULL)
{
AgentId = [rs stringForColumn:#"agent_id"];
}
else
AgentId=#"0";
Player *temp =[[Player alloc]initPlayerID:PlayerId Name:PlayerName Agent:AgentId];
[appDelegate.playerList addObject:temp];
[temp release];
}
[rs close];
[db close];
PlayersListTableViewController *temp=[[PlayersListTableViewController alloc]initWithNibName:#"PlayersListTableViewController" bundle:nil];
temp.title=#"Players";
self.playersListTableViewCtrl=temp;
[temp release];
[self.navigationController pushViewController:playersListTableViewCtrl animated:YES];
}
Here is theIBAction used to search players based on their playing position.
-(IBAction)SearchPosition
{
searchTermValue= searchPositionValue;
self.fmdbUtils = [[[FMDBUtils alloc] initWithDatabase:#"Colts.sql"] autorelease];
FMDatabase *db = [self.fmdbUtils sharedDB];
FMResultSet *rs = nil;
NSString *AgentId = nil;
NSString *PlayerName = nil;
NSString *PlayerId = nil;
ScoutAppDelegate *appDelegate = (ScoutAppDelegate *)[[UIApplication sharedApplication] delegate];
//appDelegate.playerList = [[NSMutableArray alloc] init];
NSString * query = #"SELECT * FROM Player WHERE LENGTH (lastname)>0 AND LENGTH (firstname)>0 AND ( College_Position LIKE '%' || ? || '%' OR Pro_Position LIKE'%' || ? || '%') ORDER BY lastname,firstname";
rs = [db executeQuery:query,searchPositionValue,searchPositionValue];
[query release];
while([rs next])
{
PlayerId = [rs stringForColumn:#"player_id"];
//NSString *PlayerName = [rs stringForColumn:#"Player Name"];
if ([rs stringForColumn:#"Player Name"]!= NULL)
{
PlayerName = [rs stringForColumn:#"Player Name"];
}
else
PlayerName=#"";
if ([rs stringForColumn:#"agent_id"]!= NULL)
{
AgentId = [rs stringForColumn:#"agent_id"];
}
else
AgentId=#"0";
Player *temp =[[Player alloc]initPlayerID:PlayerId Name:PlayerName Agent:AgentId];
[appDelegate.playerList addObject:temp];
[temp release];
}
[rs close];
[db close];
PlayersListTableViewController *temp=[[PlayersListTableViewController alloc]initWithNibName:#"PlayersListTableViewController" bundle:nil];
temp.title=#"Players";
self.playersListTableViewCtrl=temp;
[temp release];
[self.navigationController pushViewController:playersListTableViewCtrl animated:YES];
}
This method just gives selected playing position for search in pickerview.
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
self.searchPositionValue = [playingPositions objectAtIndex: row];
}
Try to debug the SQL-Statement (after the executeQuery: call) by printing the error:
if ([db hadError]) {
NSLog(#"DB Error %d: %#", [db lastErrorCode], [db lastErrorMessage]);
}
For developing I would recommend to enable general logging of errors:
db.logsErrors = YES;
Related
-(void) searchFieldChanged{
MPVTModelList *list = [[MPVTModelList alloc] initWithClass:[MassPOAssignmentModel class]];
[intersectionTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:1] byExtendingSelection:NO];
// [searchIntersectionField setStringValue:[[[searchIntersectionField stringValue] stringByReplacingOccurrencesOfString:#"\\" withString:kMPVTBlankString] stringByReplacingOccurrencesOfString:#"\'" withString:kMPVTBlankString]];
[searchIntersectionField setStringValue:[searchIntersectionField stringValue]];
NSArray *array=[[NSArray alloc]init];
if([[[searchIntersectionField cell]placeholderString] isEqualToString:#"Pricing Org"]){
NSArray *tempArray=[[[searchIntersectionField stringValue] uppercaseString] componentsSeparatedByString:#","];
NSLog(#"tempArray %#",tempArray);
NSString * str=[[searchIntersectionField stringValue] uppercaseString];
NSLog(#"str is %#",str);
for(id item in tempArray ){
[intersectionTableView reloadData];
array=[[[self intersectionList]entities]filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"mpoPricingOrg.stringValue contains[cd] %#",item]];
NSLog(#" item is %#",item);
NSLog(#"insie if arr %#",array);
[list appendEntities:array];
NSLog(#"hello %#",[[searchIntersectionField cell]placeholderString]);
}
}
else{
NSLog(#"inside else");
array = [[self searchFieldController] updatePredicateWithFilterText:[searchIntersectionField stringValue] searchArray:[[self intersectionList] entities] searchTableView:intersectionTableView];
NSLog(#"in side else array %#",array);
[list appendEntities:array];
}
[self setIntersectionList:list];
[list release];
[intersectionTableView reloadData];
[intersectionTableView deselectAll:nil];
[super updatePlacard:intersectionTableView];
}
I have called this method in -(void)controltextDidEditing. But when I enter "China" the filter predicate works fine. But when I enter "China,Brazil" it only shows the record for China and not for Brazil. Please suggest a better way of doing it.
I am a rookie in Xcode and I have been using the UITableViewController which shows this error.
This is the error message:
* Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
* First throw call stack:
(0x1c91012 0x10cee7e 0x1c330b4 0x36d0 0xc58d5 0xc5b3d 0xacce83 0x1c50376 0x1c4fe06 0x1c37a82 0x1c36f44 0x1c36e1b 0x1beb7e3 0x1beb668 0x1665c 0x2132 0x2065)
libc++abi.dylib: terminate called throwing an exception
(lldb)
This is my code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == 0) {
NSString *strURL = [NSString stringWithFormat:#"http://localhost:8888/GetDetail.php?choice=row0"];
NSArray *arrayImagesNames = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURL]];
arrayDataFromServer2 = [[NSMutableArray alloc]init];
NSEnumerator *enumForNames = [arrayImagesNames objectEnumerator];
id objName;
while ( objName = [enumForNames nextObject]) {
[arrayDataFromServer2 addObject:[NSDictionary dictionaryWithObjectsAndKeys:objName, #"name", nil]];
}
NSString *nn = [[arrayDataFromServer2 objectAtIndex:indexPath.row] objectForKey:#"name"];
row1 = [nn intValue];
NSLog(#"%d", row1);
CompanyProfileViewController *profile = [self.storyboard instantiateViewControllerWithIdentifier:#"Profile"];
[self.navigationController pushViewController:profile animated:YES];
profile.profileid = row1;
NSLog(#"%d", profile.profileid);
}
if (indexPath.row == 1) {
NSString *strURL = [NSString stringWithFormat:#"http://localhost:8888/GetDetail.php?choice=row1"];
NSArray *arrayImagesNames = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURL]];
arrayDataFromServer2 = [[NSMutableArray alloc]init];
NSEnumerator *enumForNames = [arrayImagesNames objectEnumerator];
id objName;
while (objName = [enumForNames nextObject]) {
[arrayDataFromServer2 addObject:[NSDictionary dictionaryWithObjectsAndKeys:objName, #"name", nil]];
}
NSString *nn = [[arrayDataFromServer2 objectAtIndex:indexPath.row] objectForKey:#"name"];
row1 = [nn intValue];
NSLog(#"%d", row1);
CompanyProfileViewController *profile = [self.storyboard instantiateViewControllerWithIdentifier:#"Profile"];
[self.navigationController pushViewController:profile animated:YES];
profile.profileid = row1;
NSLog(#"%d", profile.profileid);
}
if (indexPath.row == 2) {
NSString *strURL = [NSString stringWithFormat:#"http://localhost:8888/GetDetail.php?choice=row2"];
NSArray *arrayImagesNames = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURL]];
arrayDataFromServer2 = [[NSMutableArray alloc]init];
NSEnumerator *enumForNames = [arrayImagesNames objectEnumerator];
id objName;
while ( objName = [enumForNames nextObject]) {
[arrayDataFromServer2 addObject:[NSDictionary dictionaryWithObjectsAndKeys:objName, #"name", nil]];
}
NSString *nn = [[arrayDataFromServer2 objectAtIndex:indexPath.row] objectForKey:#"name"];
row1 = [nn intValue];
NSLog(#"%d", row1);
CompanyProfileViewController *profile = [self.storyboard instantiateViewControllerWithIdentifier:#"Profile"];
[self.navigationController pushViewController:profile animated:YES];
profile.profileid = row1;
NSLog(#"%d", profile.profileid);
}
if (indexPath.row == 3) {
NSString *strURL = [NSString stringWithFormat:#"http://localhost:8888/GetDetail.php?choice=row3"];
NSArray *arrayImagesNames = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURL]];
arrayDataFromServer2 = [[NSMutableArray alloc]init];
NSEnumerator *enumForNames = [arrayImagesNames objectEnumerator];
id objName;
while ( objName = [enumForNames nextObject]) {
[arrayDataFromServer2 addObject:[NSDictionary dictionaryWithObjectsAndKeys:objName, #"name", nil]];
}
NSString *nn = [[arrayDataFromServer2 objectAtIndex:indexPath.row] objectForKey:#"name"];
row1 = [nn intValue];
NSLog(#"%d", row1);
CompanyProfileViewController *profile = [self.storyboard instantiateViewControllerWithIdentifier:#"Profile"];
[self.navigationController pushViewController:profile animated:YES];
profile.profileid = row1;
NSLog(#"%d", profile.profileid);
}
}
When I click on the second cell (index.row == 1) this error would occur.
I have used breakpoint and the error was on the line:
"NSString *nn = [[arrayDataFromServer2 objectAtIndex:indexPath.row] objectForKey:#"name"];"
Please Help!
Swift 4
after more time i am get the love for this Error 😄
when you use the tableView from the storyboard and implementing in your code :
hint that and compare :
between the number of section and numberOfRowsInSection == storyboard and code
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 3
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 1
}
You have an array and you have either 0 or 1 elements in it. Now you are trying to extract 2nd element from it, [0] is first, and [1] is second.
EDIT:
As you are not sure when the array will contain 1 or more objects. Therefore you can use as:
NSString *nn=nil;
if([arrayDataFromServer2 count]>1){
nn = [[arrayDataFromServer2 objectAtIndex:indexPath.row] objectForKey:#"name"];
}
I am building a app for a local football club. I want to show all players names and pictures in a grid. Therefore I am using the NRGridview. But it won't load up with my data. I have an NSArray with all players information. Here you see the method which generates this array.
- (NSArray *)getTeam
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Team"];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"sortOrder" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSArray *mutableFetchResults = [self.genkDatabase.managedObjectContext executeFetchRequest:request error:&error];
NSLog(#"first error log %#", [error localizedDescription]);
if (mutableFetchResults == nil) {
NSLog(#"second error log %#", [error localizedDescription]);
}else if ([mutableFetchResults count] == 0){
NSLog(#"geen resultaten voor team");
}else{
NSLog(#"team names: %#",[mutableFetchResults valueForKey:#"name"]);
return mutableFetchResults;
}
return mutableFetchResults;
}
And this is what I do in the tableview.
- (NRGridViewCell*)gridView:(NRGridView *)gridView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyCellIdentifier = #"MyCellIdentifier";
NRGridViewCell* cell = [gridView dequeueReusableCellWithIdentifier:MyCellIdentifier];
if(cell == nil){
cell = [[NRGridViewCell alloc] initWithReuseIdentifier:MyCellIdentifier];
[[cell textLabel] setFont:[UIFont boldSystemFontOfSize:11.]];
[[cell detailedTextLabel] setFont:[UIFont systemFontOfSize:11.]];
}
NSLog(#"players array %#",players);
for (int i = 0; i <= [players count]; i++) {
// NSData *imgData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[[players objectAtIndex:i]valueForKey:#"image"]]];
// UIImage *image = [[UIImage alloc]initWithData:imgData];
//cell.imageView.image = image;
cell.textLabel.text = [[players objectAtIndex:i]valueForKey:#"name"];
cell.detailedTextLabel.text = [[players objectAtIndex:i]valueForKey:#"position"];
return cell;
}
return cell;
}
The NSLog gives always (null). My question is now, where should I put the code "NSArray *players = [self getTeam] . so that my tableview will fill up with data?
EDIT
It did give me back the right amount of sections, and numberOfRowsInsection. For numbersOfRowsIn section I created 4 methods. 1 method whichs gets all off the goalkeepers, 1 for the defenders, 1 for the wingers, and 1 for the attackers. Then In my tableview method I did the following.
- (NSInteger)gridView:(NRGridView *)gridView numberOfItemsInSection:(NSInteger)section
{
if(section == 0){
return [[self getDoelmannen]count];
}else if (section == 1){
return [[self getVerdedigers]count];
}else if (section == 2){
return [[self getMiddenvelders]count];
}else{
return [[self getAanvallers]count];
}
return [[self getAanvallers]count];
}
This works. But still have the problem for my cell self.
EDIT2
Okay I think my problem is with filling my players Array up. I do the following in my viewDidLoad
-(void)viewDidLoad{
_players = [self getTeam];
NSLog(#"players array: %#",_players);
}
Which gives the following log.
2012-10-17 12:11:22.099 RacingGenk[63122:c07] nil
2012-10-17 12:11:22.099 RacingGenk[63122:c07] players array: (null)
Here is my code for getTeam
- (NSArray *)getTeam
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Team"];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"sortOrder" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSArray *mutableFetchResults = [self.genkDatabase.managedObjectContext executeFetchRequest:request error:&error];
if (mutableFetchResults == nil) {
NSLog(#"nil");
}else if ([mutableFetchResults count] == 0){
NSLog(#"geen resultaten voor team");
}else{
NSLog(#"team names: %#",[mutableFetchResults valueForKey:#"name"]);
return mutableFetchResults;
}
return mutableFetchResults;
}
It looks like players isn't getting initialized. You can put your [self getTeam] call in the viewDidLoad method and make players a property.
If NRGridView is anything like UITableView, there are probably other methods that you need to overload.
For example, UITableView has tableView:numberOrRowsInSection:. Failure to return > 0 value from this method results in nothing being shown. Or numberOfSectionsInTableView:, which returns the number of sections and so on.
Check the documentation for the control you're using.
Update:
Since your executeFetchRequest:error: is failing, you should check if there's an error message instead of just printing out (nil):
NSLog(#"%#", [error localizedDescription]);
In my app I have a Place entity that contains reviews and featured objects at the minute my app is constantly refreshing these everytime i parse my xml data which is fine however I need to delete the review and featued objects before they are re parsed. My code is as follows and I believe I need to delete the objects in the parseXML method at the top:
-(void)parseXML:(NSString*)xml{
TBXML * tbxml = [TBXML tbxmlWithXMLString:xml];
if(tbxml.rootXMLElement){
[self traverseElement:tbxml.rootXMLElement];
if(self.tempItem){
NSLog(#"Ending Application");
[self configurePlaceChildrenAndSave];
[self startGeoCodingQueue];
}
}
}
-(void)fireGeocoder:(BSForwardGeocoder*)g{
NSLog(#"Begining FGC for %# (%#)",g.searchQuery,g.metaData);
[g findLocation];
}
-(void)startGeoCodingQueue{
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:YES] forKey:kGeoCoderInProgress];
int i = 0;
BSForwardGeocoder * fgc;
NSArray * a = [CoreDataBasicService fetchResultsForEnity:#"Place" andSortDiscriptor:#"name" Ascending:YES];
for (Place * p in a) {
if(p.latitude && p.longitude)continue;//skip geocoding if location data exists
fgc = [[BSForwardGeocoder alloc] initWithDelegate:self];
fgc.metaData = p.name;
fgc.searchQuery = p.postcode;
NSLog(#"gc:%i-%i",i,[a count]);
if([a count] == i+1){
fgc.last = YES;
}
float delay = (float)i*kGeoCoderDelay;
[self performSelector:#selector(fireGeocoder:) withObject:[fgc autorelease] afterDelay:delay];
fgc = nil;
i++;
}
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithInt:i] forKey:kGeoCoderCompletedKey];
}
-(void)finishedGeocoding{
[[NSUserDefaults standardUserDefaults] setValue:[NSDate date] forKey:kGeoCoderlastRanKey];
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:NO] forKey:kGeoCoderInProgress];
[[NSNotificationCenter defaultCenter] postNotificationName:kGeoCoderNotificationName object:nil];
}
-(void)forwardGeocoderError:(BSForwardGeocoder *)geocoder errorMessage:(NSString *)errorMessage{
NSLog(#"EX ERROR: GEOCODER FAILED - %#",errorMessage);
if(geocoder.last)[self finishedGeocoding];
}
- (void)forwardGeocoderFoundLocation:(BSForwardGeocoder*)geocoder
{
if(geocoder.status == G_GEO_SUCCESS)
{
BSKmlResult *result = [geocoder.results lastObject];
if(!result)return;
//[self.fowardGeocodingQueue setObject:[NSString stringWithString:value] forKey:self.tempItem.name];
Place * p = [CoreDataBasicService fetchPlaceNamed:geocoder.metaData];
p.latitude = [NSNumber numberWithFloat:result.latitude];
p.longitude = [NSNumber numberWithFloat:result.longitude];
[CoreDataBasicService saveChanges];
//NSLog(#"%# - %f,%f",p2.name,p2.latitude,p2.longitude);
NSLog(#"completed Foward geocoding for '%#' (%#) [%f,%f]",geocoder.metaData,geocoder.searchQuery,[p.latitude floatValue],[p.longitude floatValue]);
if(geocoder.last)[self finishedGeocoding];
}
else {
NSString *message = #"";
switch (geocoder.status) {
case G_GEO_BAD_KEY:
message = #"The API key is invalid.";
break;
case G_GEO_UNKNOWN_ADDRESS:
message = [NSString stringWithFormat:#"Could not find %#", geocoder.searchQuery];
break;
case G_GEO_TOO_MANY_QUERIES:
message = #"Too many queries has been made for this API key.";
break;
case G_GEO_SERVER_ERROR:
message = #"Server error, please try again.";
break;
default:
break;
}
NSLog(#"ERROR: GEOCODER FAILED - %#",message);
// UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Information"
// message:message
// delegate:nil
// cancelButtonTitle:#"OK"
// otherButtonTitles: nil];
// [alert show];
// [alert release];
}
}
-(void)configurePlaceChildrenAndSave{
if(self.tempReviewArray.count==0 && self.tempReview)[self.tempReviewArray addObject:self.tempReview];
if(self.tempFeatureArray.count==0 && self.tempFeature)[self.tempFeatureArray addObject:self.tempFeature];
[self.tempItem setReviews:self.tempReviewArray];
[self.tempItem setFeatured:self.tempFeatureArray];
self.tempReviewArray = nil;
self.tempReview = nil;
self.tempFeatureArray = nil;
self.tempFeature = nil;
[CoreDataBasicService saveChanges];
self.tempItem = nil;
}
-(NSString*)formatKeyForCoreData:(NSString*)elementKey{
return [elementKey stringByReplacingOccurrencesOfString:#"-" withString:#""];
}
-(NSDate*)convertStringDateToDate:(NSString*)stringDate{
NSDateFormatter * df = [[NSDateFormatter alloc] init];
NSLog(#"DATE:%#",stringDate);
[df setDateFormat:#"y-M-d'T'H:m:s'Z'"];
NSDate * d = [df dateFromString:stringDate];
[df release];
return d;
}
-(Place*)getPlaceForName:(NSString*)name{
NSPredicate * pred = [NSPredicate predicateWithFormat:#"name = %#",name];
NSArray * results = [CoreDataBasicService fetchResultsForEnity:#"Place" WithPredicate:pred andSortDiscriptor:#"identifier" Ascending:YES];
return [results lastObject];
}
-(void)traverseElement:(TBXMLElement *)element {
do {
// Display the name of the element
NSString * value = [TBXML textForElement:element];
NSLog(#"%#-'%#'",[TBXML elementName:element],value);
// Obtain first attribute from element
NSString * ele = [TBXML elementName:element];
if([ele isEqualToString:#"place"]){
if(self.tempItem){
//GEOCODER HERE
[self configurePlaceChildrenAndSave];
}
//CREATE NEW CD ITEM HER
if(dataBaseExits){
TBXMLElement * idElement = [TBXML childElementNamed:#"name" parentElement:element];
Place * p = [self getPlaceForName:[NSString stringWithFormat:#"%#",[TBXML textForElement:idElement]]];
if(p){
[self setTempItem:p];
TBXMLElement * reviewsElement = [TBXML childElementNamed:#"reviews" parentElement:element];
if(reviewsElement){
self.tempItem.reviews = nil;
[CoreDataBasicService saveChanges];
[self traverseElement:reviewsElement];
}
TBXMLElement * promosElement = [TBXML childElementNamed:#"featured-places" parentElement:element];
if(promosElement){
self.tempItem.featured = nil;
[CoreDataBasicService saveChanges];
[self traverseElement:promosElement];
}
[CoreDataBasicService saveChanges];
continue;
}
I'm trying to add a Search bar to my UITableView. I followed this tutorial: http://clingingtoideas.blogspot.com/2010/02/uitableview-how-to-part-2-search.html.
I'm getting this error if I type a letter in the search box: Rooster(10787,0xa05ed4e0) malloc: *** error for object 0x3b5f160: double free
*** set a breakpoint in malloc_error_break to debug.
This error occurs here:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self handleSearchForTerm:searchString];
return YES;
}
(on the second line)
- (void)handleSearchForTerm:(NSString *)searchTerm {
[self setSavedSearchTerm:searchTerm];
if ([self searchResults] == nil) {
NSMutableArray *array = [[NSMutableArray alloc] init];
[self setSearchResults:array];
[array release];
}
//Empty the searchResults array
[[self searchResults] removeAllObjects];
//Check if the searchTerm doesn't equal zero...
if ([[self savedSearchTerm] length] != 0) {
//Search the whole tableList (datasource)
for (NSString *currentString in tableList) {
NSString *klasString = [[NSString alloc] init];
NSInteger i = [[leerlingNaarKlasList objectAtIndex:[tableList indexOfObject:currentString]] integerValue];
if(i != -1) {
klasString = [klassenList objectAtIndex:(i - 1)];
}
//Check if the string matched or the klas (group of school)
if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound ||
[klasString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound) {
//Add to results
[[self searchResults] addObject:currentString];
//Save the klas (group of school). It has the same index as the result (lastname)
NSString *strI = [[NSString alloc] initWithFormat:#"%i", i];
[[self searchResultsLeerlingNaarKlas] addObject:strI];
[strI release];
}
[klasString release];
}
}
}
Can someone help me out?
Regards,
Dodo
The double free error means you have released an object more than needed. Here the suspicious object is klasString.
From your code:
NSString *klasString = [[NSString alloc] init];
...
if(i != -1) {
klasString = [klassenList objectAtIndex:(i - 1)];
}
...
[klasString release];
The assignment inside the if statement
loses reference to the newly allocated NSString, introducing a memory leak
makes the later release apply to the object from klassenList. When klassenList releases its elements, a double free error will occur.