0

有我的问题,我有一个应用程序有大量的数据。我的 .plist 文件包含元素数组,它看起来像这样 - 橙色、蛋白质 - 25、碳水化合物 - 40、脂肪 - 50 等。总共,每个项目包含 7 行带有数据的子行。

我的 tableview 在一个巨大的 tableview 中显示了所有带有部分的数组。在屏幕顶部我有一个搜索栏。当我点击搜索栏并输入任何字母时,它会显示这样的新数组 - M:巨无霸、肉类、膳食等。

所以,在我的数组中达到 700 多个元素之前,一切都很好,但是,当我添加最后 500 个元素(我的 .plist 文件从 200 到 700 个元素编辑)时,我意识到当我点击搜索并输入任何字母时,我有很大的延迟。第一次延迟大约 0.6 秒(当我点击搜索字段时),在我按下键盘上的按钮后第二次延迟(再次大约 0.6 秒)。我认为,那是因为我在我的 .plist 中添加了许多项目。

显然,我不想减少数组中对象的数量。我想我有“坏”的代码,我向你寻求任何有用的建议。请帮助我,我想我需要改进它!有我的代码,其中包含我的 UITableView 代码和搜索方法:

- (void)viewDidLoad 
{
    [super viewDidLoad];

    self.tableView.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg.png"]];


    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"food.plist"];

    listOfItems = [[NSMutableArray alloc]initWithContentsOfFile:path];
    searchListOfItems = [[NSMutableArray alloc]init];

    searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 45)];
    searchBar.barStyle = UIBarStyleBlackTranslucent;
    searchBar.showsCancelButton = NO;
    searchBar.autocorrectionType=UITextAutocorrectionTypeNo;
    searchBar.autocapitalizationType=UITextAutocapitalizationTypeNone;
    searchBar.delegate= self; 
    [[self tableView] setTableHeaderView:searchBar];


    searching = NO;
    letUserSelectRow = YES;
    UIBarButtonItem *addButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addProduct:)];
    self.navigationItem.leftBarButtonItem = addButton;
    self.navigationItem.backBarButtonItem.title = @"Back";


    [self.tableView reloadData];

    self.navigationItem.backBarButtonItem =
    [[UIBarButtonItem alloc] initWithTitle:@"Назад"
                                     style:UIBarButtonItemStyleBordered
                                    target:nil
                                    action:nil];




    self.title = @"Продукты";
    UILabel* tlabel=[[UILabel alloc] initWithFrame:CGRectMake(0,0, 125, 21)];
    tlabel.text=self.navigationItem.title;
    tlabel.font = [UIFont fontWithName:@"Chalkboard SE" size:17];
    tlabel.textAlignment = UITextAlignmentCenter;
    tlabel.textColor=[UIColor whiteColor];
    tlabel.backgroundColor =[UIColor clearColor];
    tlabel.adjustsFontSizeToFitWidth=YES;
    self.navigationItem.titleView=tlabel;


}

- (void)hideModalViewController:(NSNotification *)notif
{
    [self dismissModalViewControllerAnimated:YES];
    [self viewDidLoad];   
}

-(void)productAdded {
    [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentSize.height - self.tableView.frame.size.height)];
    [self.tableView reloadData];
}

- (void)addProduct:(UIBarButtonItem *)button
{
    BIDAddProductViewController *addProductVC = [[BIDAddProductViewController alloc]init];
    addProductVC.delegate = self;
    [self.navigationController pushViewController:addProductVC animated:YES];

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(hideModalViewController:) name:@"HideModalViewController" object:addProductVC];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.childController = nil;
    self.tableView=nil;

}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{

    NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];

    if (editingStyle == UITableViewCellEditingStyleDelete)

    {

        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject]stringByAppendingPathComponent:@"food.plist"];

        NSMutableArray *listOfItemsToDelete = [[NSMutableArray alloc]initWithContentsOfFile:path];

        [[[listOfItemsToDelete objectAtIndex:indexPath.section]objectForKey:@"Products"] removeObjectAtIndex:indexPath.row];
        [listOfItemsToDelete writeToFile:path atomically:YES];
        [self viewDidLoad];


        NSArray *descriptionsArray = [[dictionary objectForKey:@"Products"]valueForKeyPath:@"ProductName"];

        NSLog(@"%@", descriptionsArray);
        NSLog(@"%i", [descriptionsArray count]);

        if ([descriptionsArray count]<2){


            [listOfItems removeObjectAtIndex:indexPath.section];
            [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:NO];
            [listOfItems writeToFile:path atomically:YES];
        }



        }
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellEditingStyleDelete;
}

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



    static NSString *SectionsTableIdentifier = @"SectionsTableIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
                             SectionsTableIdentifier];



    if (cell == nil) {
        cell = [[UITableViewCell alloc]
                initWithStyle:UITableViewCellStyleValue1
                reuseIdentifier:SectionsTableIdentifier];
    }

    if(searching)
        cell.textLabel.text = [[searchListOfItems objectAtIndex:indexPath.row]valueForKey:@"ProductName"];
    else {

        NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
         NSArray *array = [[dictionary objectForKey:@"Products"]valueForKeyPath:@"ProductName"];
        NSString *cellValue = [array objectAtIndex:indexPath.row];
        cell.textLabel.text = cellValue;


    }


    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
    return cell;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    if (searching)
        return 1;
    else
        return [listOfItems count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    if (searching)
        return [searchListOfItems count];
    else {

        NSDictionary *dictionary = [listOfItems objectAtIndex:section];
        NSArray *array = [dictionary objectForKey:@"Products"];
        return [array count];
    }
}

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

    if(searching)
        return @"";

   return [[listOfItems objectAtIndex:section]valueForKey:@"SectionName"];
}

- (void) doneSearching_Clicked:(id)sender {

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

    letUserSelectRow = YES;
    searching = NO;
    self.navigationItem.rightBarButtonItem = nil;
    self.tableView.scrollEnabled = YES;
    [self.tableView reloadData];

}
- (void) searchBarSearchButtonClicked:(UISearchBar *)theSearchBar {

    [self searchTableView];
}

- (void) searchTableView {

    NSString *searchText = searchBar.text;
    NSMutableArray *searchArray = [[NSMutableArray alloc] init];

    for (NSDictionary *dictionary in listOfItems)
    {
        NSArray *array = [dictionary objectForKey:@"Products"];
        [searchArray addObjectsFromArray:array];
    }

    for (NSString *sTemp in [searchArray valueForKeyPath:@"ProductName"] )
    {
        NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];

        if (titleResultsRange.length > 0)
            [searchListOfItems addObject:[searchArray objectAtIndex:[[searchArray valueForKeyPath:@"ProductName"]indexOfObject:sTemp]]];
    }

    searchArray = nil;
}
- (NSIndexPath *)tableView :(UITableView *)theTableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    if(letUserSelectRow)
        return indexPath;
    else
        return nil;
}
- (void) searchBarTextDidBeginEditing:(UISearchBar *)theSearchBar {

    searching = YES;

    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]
                                               initWithBarButtonSystemItem:UIBarButtonSystemItemDone
                                               target:self action:@selector(doneSearching_Clicked:)];
}

- (void)searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {

    [searchListOfItems removeAllObjects];

    if([searchText length] > 0) {

        searching = YES;
        letUserSelectRow = YES;
        self.tableView.scrollEnabled = YES;
        [self searchTableView];
    }
    else {

        searching = NO;
        letUserSelectRow = NO;
        self.tableView.scrollEnabled = NO;
    }

    [self.tableView reloadData];
}
- (void)viewWillAppear:(BOOL)animated
{


    letUserSelectRow = YES;
    [super viewWillAppear:animated];


}

#pragma mark -
#pragma mark Table Delegate Methods
- (void)tableView:(UITableView *)tableView
    didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    if (childController == nil) {
        childController = [[BIDDisclosureDetailController alloc]
                           initWithNibName:@"BIDDisclosureDetail" bundle:nil];
    }

        if(searching)

        {


            childController.description = [[searchListOfItems objectAtIndex:indexPath.row]valueForKey:@"ProductName"];
//            childController.title = [[searchListOfItems objectAtIndex:indexPath.row]valueForKey:@"ProductName"];
            childController.calories = [[searchListOfItems objectAtIndex:indexPath.row]valueForKey:@"Calories"];
            childController.protein = [[searchListOfItems objectAtIndex:indexPath.row]valueForKey:@"Proteins"];
            childController.carbohydrates = [[searchListOfItems objectAtIndex:indexPath.row]valueForKey:@"Carbohydrates"];
            childController.fat = [[searchListOfItems objectAtIndex:indexPath.row]valueForKey:@"Fat"];
            childController.myBool=[[searchListOfItems objectAtIndex:indexPath.row]valueForKey:@"TextField"];

        }

        else 

        {


            NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];

            NSArray *descriptionsArray = [[dictionary objectForKey:@"Products"]valueForKeyPath:@"ProductName"];
            childController.description = [descriptionsArray objectAtIndex:indexPath.row];


            NSArray *proteinArray = [[dictionary objectForKey:@"Products"]valueForKeyPath:@"Proteins"];
            childController.protein = [proteinArray objectAtIndex:indexPath.row];

            NSArray *carbohydratesArray = [[dictionary objectForKey:@"Products"]valueForKeyPath:@"Carbohydrates"];
            childController.carbohydrates = [carbohydratesArray objectAtIndex:indexPath.row];

            NSArray *fatArray = [[dictionary objectForKey:@"Products"]valueForKeyPath:@"Fat"];
            childController.fat = [fatArray objectAtIndex:indexPath.row];

            NSArray *caloriesArray = [[dictionary objectForKey:@"Products"]valueForKeyPath:@"Calories"];
            childController.calories = [caloriesArray objectAtIndex:indexPath.row];

             NSArray *textFieldArray = [[dictionary objectForKey:@"Products"]valueForKeyPath:@"TextField"];
            childController.myBool = [textFieldArray    objectAtIndex:indexPath.row];






        }

        [self.navigationController pushViewController:childController
                                             animated:YES];
    }

@end
4

2 回答 2

1

In your code every time you change the text in the search bar the searchTableView function is run. You will want to make sure this function is as quick as possible.

I see you are iterating over the list of NSDictionarys from the plist file in the function and building a search array. If the plist is large this is probably quite expensive of an operation to be doing on every text change.

for (NSDictionary *dictionary in listOfItems)
{
    NSArray *array = [dictionary objectForKey:@"Products"];
    [searchArray addObjectsFromArray:array];
}

I think if you moved this iteration to viewDidLoad and made searchArray a global variable you will notice some speed increases.

Hope this helps.

于 2012-06-16T13:55:54.480 回答
0

I think you should use SqliteDatabase to store so much data,and use SQL to search your data.Every time you touch search bar,all of your data alloc in a new NSMutableArray with the method

-(void)searchTableView 

this is why when you touch the search bar , it will delay 0.6sec when your data is too much

于 2012-06-16T13:58:23.560 回答