iOS UITableView拥有10,000条记录的SQLite DB

时间:2014-04-15 17:50:36

标签: objective-c sqlite uitableview

我的iOS应用程序从Web查询填充SQLlite数据库(使用FMDB)。有一个UITableView来显示这些数据。自从我开始编写应用程序以来,这个数据库的大小已爆炸到大约10,000条记录。

我目前的设计是从数据库中加载数据,然后在UITableView中使用它。它工作正常,我在屏幕右侧有字母顺序索引,供用户快速访问数据。

问题当然是加载阵列需要15-20秒。我最初设计这个是在每次用户点击UITableView时加载,但这意味着每次15-20秒。

是否有办法在保留搜索功能和索引的同时仅在UITableView中加载某些数据?

我可以/应该加载一次数组并重复使用它吗?我试过了,但似乎无法完成这项工作。

作为最后的手段,我可​​以切换到CoreData,但我真的不想在中游换马。

UITableView实施:

    #import "ContactViewController.h"
    #import "ContactDetailViewController.h"

    @interface ContactViewController ()
    @end

    @implementation ContactViewController {

      NSMutableArray *_contacts;
      UISearchDisplayController *searchController;
      BOOL isSearching;
    }

    - (void)awakeFromNib {
      if ([[UIDevice currentDevice] userInterfaceIdiom] ==
          UIUserInterfaceIdiomPad) {
        self.clearsSelectionOnViewWillAppear = NO;
        self.preferredContentSize = CGSizeMake(320.0, 600.0);
      }
      [super awakeFromNib];
    }

    - (void)viewDidLoad {

      [super viewDidLoad];

      // Get array of employees and sections
      _contacts = [ContactsDatabase getContacts];
      self.sections = [ContactsDatabase getSections:_contacts];

      // Set up Search
      self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
      self.filteredContacts = [NSMutableArray array];
      searchController.delegate = self;
      searchController.searchResultsDataSource = self;
      isSearching = FALSE;

      // iPad
      // self.dtailViewController = (detailViewController
      // *)[[self.splitViewController.viewControllers lastObject]
      // topViewController];

      // Set the back bar button
      UIBarButtonItem *backButton =
          [[UIBarButtonItem alloc] initWithTitle:@"Contacts"
                                           style:UIBarButtonItemStylePlain
                                          target:nil
                                          action:nil];
      self.navigationItem.backBarButtonItem = backButton;
    }

    #pragma mark - Table View
    - (NSInteger)tableView:(UITableView *)tableView
        numberOfRowsInSection:(NSInteger)section {
      NSInteger tmpRows;
      if (tableView == self.searchDisplayController.searchResultsTableView) {
        tmpRows = [self.filteredContacts count];
      } else {
        tmpRows = [[self.sections
            valueForKey:[[[self.sections allKeys]
                            sortedArrayUsingSelector:
                                @selector(localizedCaseInsensitiveCompare:)]
                            objectAtIndex:section]] count];
      }
      return tmpRows;
    }

    - (UITableViewCell *)tableView:(UITableView *)tableView
             cellForRowAtIndexPath:(NSIndexPath *)indexPath {

      static NSString *CellIdentifier = @"Cell";
      UITableViewCell *cell =
          [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
      if (cell == nil) {
        cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
      }

      if (isSearching) {
        contact *thisContact = [self.filteredContacts objectAtIndex:indexPath.row];
        cell.textLabel.text = thisContact.cmpNme;
      } else {
        contact *thisContact = [[self.sections
            valueForKey:[[[self.sections allKeys]
                            sortedArrayUsingSelector:
                                @selector(localizedCaseInsensitiveCompare:)]
                            objectAtIndex:indexPath.section]]
            objectAtIndex:indexPath.row];
        cell.textLabel.text = thisContact.cmpNme;
      }

      return cell;
    }

    #pragma mark - Table Sections
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
      NSInteger tmpCount;
      if (isSearching) {
        tmpCount = 1;
      } else {
        tmpCount = [[self.sections allKeys] count];
      }
      return tmpCount;
    }

    - (NSString *)tableView:(UITableView *)tableView
        titleForHeaderInSection:(NSInteger)section {

      NSString *tmpString;
      if (tableView == self.searchDisplayController.searchResultsTableView) {
        tmpString = nil;
      } else {
        tmpString = [[[self.sections allKeys]
            sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]
            objectAtIndex:section];
      }
      return tmpString;
    }

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
      if ([[segue identifier] isEqualToString:@"showContactDetail"]) {

        contact *dtlContact;

        if (isSearching) {
          dtlContact = [self.filteredContacts
              objectAtIndex:self.searchDisplayController.searchResultsTableView
                                .indexPathForSelectedRow.row];
        } else {
          dtlContact = [[self.sections
              valueForKey:[[[self.sections allKeys]
                              sortedArrayUsingSelector:
                                  @selector(localizedCaseInsensitiveCompare:)]
                              objectAtIndex:[self.tableView indexPathForSelectedRow]
                                                .section]]
              objectAtIndex:[self.tableView indexPathForSelectedRow].row];
        }

        self.contactDetailViewController.detailItem = dtlContact;
        [[segue destinationViewController] setDetailItem:dtlContact];
      }
    }

    #pragma mark - Right side bar alphabetical index
    - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {

      NSArray *tmpTitle;
      if (isSearching) {
        tmpTitle = nil;
      } else {
        tmpTitle = [[self.sections allKeys]
            sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
      }
      return tmpTitle;
    }

    #pragma mark - Search methods
    - (void)searchDisplayControllerWillBeginSearch:
                (UISearchDisplayController *)controller {
      isSearching = TRUE;
      self.searchDisplayController.searchBar.showsCancelButton = YES;
      [self.tableView reloadSectionIndexTitles];
    }

    - (void)searchDisplayControllerDidEndSearch:
                (UISearchDisplayController *)controller {
      isSearching = FALSE;
      self.searchDisplayController.searchBar.showsCancelButton = NO;
      [self.tableView reloadSectionIndexTitles];
    }

    - (void)filterContentForSearchText:(NSString *)searchText
                                 scope:(NSString *)scope {

      [self.filteredContacts removeAllObjects];

      NSPredicate *predicate =
          [NSPredicate predicateWithFormat:@"cmpNme contains[c] %@", searchText];
      NSArray *tempArray = [_contacts filteredArrayUsingPredicate:predicate];

      // Move to filtered array
      self.filteredContacts = [NSMutableArray arrayWithArray:tempArray];
      self.sections = [ContactsDatabase getSections:_contacts];
    }

    - (BOOL)searchDisplayController:(UISearchDisplayController *)controller
        shouldReloadTableForSearchString:(NSString *)searchString {

      isSearching = TRUE;
      [self
          filterContentForSearchText:searchString
                               scope:[self.searchDisplayController.searchBar
                                             .scopeButtonTitles
                                         objectAtIndex:
                                             self.searchDisplayController.searchBar
                                                 .selectedScopeButtonIndex]];
      return YES;
    }

    @end

getContacts方法

    + (NSMutableArray *)getContacts {

      id tmpDatabasePath = [(AppDelegate *)
          [[UIApplication sharedApplication] delegate] databasePathContacts];
      NSMutableArray *tmpContacts;
      tmpContacts = [[NSMutableArray alloc] init];

      FMDatabase *db = [FMDatabase databaseWithPath:tmpDatabasePath];
      [db open];
      FMResultSet *results =
          [db executeQuery:@"SELECT * FROM contacts ORDER by cmpNme"];
      while ([results next]) {
        contact *thisContact = [contact new];
        thisContact.cmpNme = [results stringForColumn:@"cmpNme"];
        thisContact.fstNme = [results stringForColumn:@"fstNme"];
        thisContact.lstNme = [results stringForColumn:@"lstNme"];
        thisContact.cntTyp = [results stringForColumn:@"cnttyp"];
        NSString *tst = [results stringForColumn:@"phnNbr"];
        thisContact.phnNbr = [NSNumber numberWithInt:[tst intValue]];
        thisContact.adr1 = [results stringForColumn:@"adr1"];
        thisContact.adr2 = [results stringForColumn:@"adr2"];
        thisContact.cty = [results stringForColumn:@"cty"];
        thisContact.ste = [results stringForColumn:@"ste"];
        tst = [results stringForColumn:@"zip"];
        thisContact.zip = [NSNumber numberWithInt:[tst intValue]];
        thisContact.ema = [results stringForColumn:@"ema"];
        tst = [results stringForColumn:@"id"];
        thisContact.id = [NSNumber numberWithInt:[tst intValue]];
        [tmpContacts addObject:thisContact];
      }
      [db close];
      return tmpCon

0 个答案:

没有答案