0

私の問題があります。かなりの量のデータを持つアプリケーションがあります。私の .plist ファイルには要素の配列が含まれています。オレンジ、タンパク質 - 25、炭水化物 - 40、脂肪 - 50 などです。合計で、各項目にはデータを含む 7 行のサブ行が含まれています。

私のテーブルビューは、セクションとともに表示されるすべての配列を、1 つの大きな巨大なテーブルビューに表示します。画面上部に検索バーがあります。検索バーをタップして任意の文字を入力すると、M: Big Mac、Meat、Meals などの新しい配列が表示されます。

したがって、配列内の 700 個以上の要素に到達する前はすべて問題ありませんでしたが、最後の 500 個の要素 (.plist ファイルを 200 個から 700 個の要素に編集) を追加すると、検索をタップして任意の文字を入力すると、大きな遅延があります。最初の遅延は約0.6秒(検索フィールドをタップしたとき)、キーボードのボタンを押した後の2番目の遅延(約0.6秒)。これは、.plist に多くの項目を追加したためだと思います。

明らかに、配列内のオブジェクトの数を減らしたくありません。私は「悪い」コードを持っていると思います。役立つアドバイスがあればお願いします。私を助けてください、私はそれを改善する必要があると思います! 私のUITableViewコードとSearchメソッドを含む私のコードがあります:

- (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

検索バーのテキストを変更するたびに、コードで searchTableView 関数が実行されます。この関数ができるだけ高速であることを確認する必要があります。

関数内の plist ファイルから NSDictionarys のリストを繰り返し処理し、検索配列を作成しているようです。plist が大きい場合、テキストを変更するたびに操作を行うには、おそらくかなりのコストがかかります。

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

この繰り返しを viewDidLoad に移動し、searchArray をグローバル変数にすると、速度が向上することに気付くと思います。

お役に立てれば。

于 2012-06-16T13:55:54.480 に答える
0

SqliteDatabase を使用して大量のデータを保存し、SQL を使用してデータを検索する必要があると思います。検索バーに触れるたびに、すべてのデータがメソッドを使用して新しい NSMutableArray に割り当てられます。

-(void)searchTableView 

これが、検索バーをタッチすると、データが多すぎると 0.6 秒遅れる理由です。

于 2012-06-16T13:58:23.560 に答える