I've created a database for the iphone using sqlite and the fmdb wrapper.
The database has roughly 3500 rows in it. It has 14 columns: 1 for an id, 1 for a name/main search term, 9 other columns for alternative search terms and 3 other columns for short descriptions.
My app's first view is just an introductory screen displaying a search bar, a bit like google. After implementing the search bar, it will bring you to another view containing a table featuring the desired results. There is a 1 or 2 second delay in this initial transition between views. Furthermore, the table doesn't allow for seamless scrolling. Finally, when you select a table cell, it brings you to a final view seamlessly, but when you try to return to the table view, there is another 1 or 2 second delay.
I've run this app with a smaller database that has 3500 rows but only 5 columns. In this case, the 9 alternative search terms are deleted from the database. When I run the app like this on the iphone, it is rather efficient... there is a small delay but it really isn't noticeable... I probably wouldn't have picked up on the lag, (I would just have assumed that the small delay is normal), if it wasn't so apparent with the larger database that I use.
I've come to the conclusion that the sqlite database needs some tweaking and thus, I have two main questions.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"CustomCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
Data *data = [[[DataController instance]filterDataWithName:searchString:searchString:searchString:searchString:searchString:searchString:searchString:searchString:searchString:searchString]objectAtIndex:indexPath.row];
cell.textLabel.text = data.aDataName;
cell.detailTextLabel.text = data.aDataStatus;
// Configure the cell.
return cell;
}
-(NSMutableArray*)filterDataWithName:(NSString*)aDataName:(NSString*)altSearchTermA:(NSString*)altSearchTermB:(NSString*)altSearchTermC:(NSString*)altSearchTermD:(NSString*)altSearchTermE:(NSString*)altSearchTermF:(NSString*)altSearchTermG:(NSString*)altSearchTermH:(NSString*)altSearchTermI;
{
if ((aDataName && [aDataName length] > 0) && (altSearchTermA && [altSearchTermA length] > 0) && (altSearchTermB && [altSearchTermB length] > 0) && (altSearchTermC && [altSearchTermC length] > 0) && (altSearchTermD && [altSearchTermD length] > 0) && (altSearchTermE && [altSearchTermE length] > 0) && (altSearchTermF && [altSearchTermF length] > 0) && (altSearchTermG && [altSearchTermG length] > 0) && (altSearchTermH && [altSearchTermH length] > 0) && (altSearchTermI && [altSearchTermI length] > 0))
{
NSMutableArray *filterDataArray = [[NSMutableArray alloc]initWithArray:dataList];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(aDataName CONTAINS[cd] %@) OR (altSearchTermA CONTAINS[cd] %@) OR (altSearchTermB CONTAINS[cd] %@) OR (altSearchTermC CONTAINS[cd] %@) OR (altSearchTermD CONTAINS[cd] %@) OR (altSearchTermE CONTAINS[cd] %@) OR (altSearchTermF CONTAINS[cd] %@) OR (altSearchTermG CONTAINS[cd] %@) OR (altSearchTermH CONTAINS[cd] %@) OR (altSearchTermI CONTAINS[cd] %@)", aDataName, altSearchTermA,altSearchTermB,altSearchTermC,altSearchTermD,altSearchTermE,altSearchTermF,altSearchTermG,altSearchTermH,altSearchTermI];
[filterDataArray filterUsingPredicate:predicate];
return filterDataArray;
}
else
{
return dataList;
}
}
The cellForRowAtIndexPath is called for each cell created, so your filterDataWithName function is being called for every cell/row.
Call your filterDataWithName somewhere else, and just use the NSMutableArray in cellForRowAtIndexPath with something like
cell.textLabel.text = [[filterDataArray objectAtIndex:indexpath.row] data.aDataName];
Ok - I missed the problem above as mentioned by Darren - if this doesn't fix it ..... I encountered a similar problem where I needed to run an exhaustive search on table. You could try restricting your query to one row with something like this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
Level2CustomCell *cell = (Level2CustomCell*) [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil)
{
cell = [[[Level2CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
}
// SEARCH ENGINE TIME
NSString *likeTitle = [NSString stringWithFormat:@" TITLE LIKE '%@%@%@'",@"%",msgView.searchBar.text,@"%"];
NSString *likeSearch = [NSString stringWithFormat:@" SORT4='%@' AND SEARCH LIKE '%@%@%@'",selectedSection,@"%",msgView.searchBar.text,@"%"];
NSString *likeAddress = [NSString stringWithFormat:@" SORT4='%@' AND ADDRESS LIKE '%@%@%@'",selectedSection,@"%",msgView.searchBar.text,@"%"];
NSString *likeContent = [NSString stringWithFormat:@" SORT4='%@' AND CONTENT LIKE '%@%@%@'",selectedSection,@"%",msgView.searchBar.text,@"%"];
qry = [NSString stringWithFormat: @"select * from SPOT_INFO WHERE SORT4 = '%@' AND %@ OR %@ OR %@ OR %@ order by TITLE limit 1 offset %d",selectedSection,likeTitle,likeSearch,likeAddress,likeContent,[indexPath row]];
DLog(@"qry :%@",qry);
FMResultSet *rs = [appDelegate.userdb executeQuery:qry];
if ([rs next]) {
NSString *title = [rs stringForColumn:@"TITLE"];
DLog(@"title %@",title);
NSString *content = [rs stringForColumn:@"CONTENT"];
NSString *imgFileName = [rs stringForColumn:@"IMG_NAME"];
}
[rs close];
}
I recommend egodatabase which has non blocking gcd (grand central dispatch) code https://github.com/jdp-global/egodatabase
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.