0

我有一个 UITableView 填充用户查找的搜索结果。为了做到这一点,我使用了一个 NSMutableArray 的字典,其中为前 10 个添加对象,然后当用户滚动到底部时,它会填充下一个 10,直到没有结果可显示。

这一切都很好,但我开始注意到完成的搜索越多,表格越慢。这是一些代码:

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
    [self.objectsArray removeAllObjects];
    [self.objectsArray setArray:nil];
    [itemsTable reloadData];
    [itemsTable scrollRectToVisible:CGRectMake(0, 0, 0, 0) animated:false];

    [self loadItemsFromURL:searchURL withItemDescription:encodedString atStartRow:start andEndRow:end];
}

以上是执行新搜索时。然后它执行一个 NSURLConnection 并用这个来响应:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if (self.objectsArray == nil)
        self.objectsArray = [NSMutableArray array]; 
        // self.objectsArray = [[NSMutableArray alloc] init];
    NSError *error;
    NSDictionary *returnArray = [[NSJSONSerialization JSONObjectWithData:itemsData options:kNilOptions error:&error] valueForKey:@"items"];
    for (id key in returnArray)
    {
        [self.objectsArray addObject:[returnArray objectForKey:key]];
    }
    counter += 10;
    [itemsTable reloadData];
}

如您所见,如果用户进行新搜索,所有对象都将被删除,[self.objectsArray removeAllObjects]我什至尝试将数组设置为nil. 如果我执行多次搜索,UITableView每次滚动都会变得越来越慢。几乎就像控制器看到数组随着每次搜索而变得越来越大,即使我在搜索之前从中删除了所有对象。有什么想法,或者我是否以错误的方式解决这个问题?

编辑: 这是cellForRowAtIndexPath:方法。cell是一个子类UITableViewCell

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Product Cell";
    static NSString *LoadCellIdentifier = @"Loading Cell";
    cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if ([self.objectsArray count] <= 0 )
    {
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        cell.itemName.text = @"No items found.";
        cell.itemPrice.text = @"";
        cell.itemLocation.text = @"";
        cell.addButton.hidden = YES;
    }
    else
    {
        if ([indexPath row] == [self.objectsArray count])
        {
            if ( [self.objectsArray count] >= 10 )
            {
                if ( [self.objectsArray count] < counter)
                {
                    cell = [tableView dequeueReusableCellWithIdentifier:LoadCellIdentifier];
                    [cell.loadingSpinner stopAnimating];
                    cell.itemName.text = @"No more items found.";
                }
                else
                {
                    if (!running)
                    {
                        [self loadItemsFromURL:searchURL withItemDescription:encodedString atStartRow:[self.objectsArray count] + 1 andEndRow:[self.objectsArray count] + 10];
                        cell = [tableView dequeueReusableCellWithIdentifier:LoadCellIdentifier];
                        cell.itemName.text = @"Loading more items...";
                        [cell.loadingSpinner startAnimating];
                        running = true;
                    }
                    else
                    {
                        cell = [tableView dequeueReusableCellWithIdentifier:LoadCellIdentifier];
                        [cell.loadingSpinner startAnimating];
                    }
                }
            }
        }
        else
        {
            cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            NSArray *match = [self.objectsArray objectAtIndex:[indexPath row]];
            cell.addButton.hidden = NO;
            if ([match valueForKey:@"DESCRIPTION"] == [NSNull null] )
            {
                cell.itemName.text = @"Description not available.";
            }
            else
            {
                cell.itemName.text = [match valueForKey:@"DESCRIPTION"];
            }
            if ([match valueForKey:@"AD"] != [NSNull null])
            {
                NSMutableString *adString = [NSMutableString stringWithString:[match valueForKey:@"AD"]];
                NSRange textRange;
                textRange = [adString rangeOfString:@"1/"];
                if (textRange.location != NSNotFound)
                {
                    [adString replaceCharactersInRange:[adString rangeOfString:@"1/"] withString:@"$"];
                }
                else
                {
                    [adString replaceCharactersInRange:[adString rangeOfString:@"/"] withString:@"/$"];
                }
                cell.itemPrice.text = adString;
            }
            else if ([match valueForKey:@"REGULAR"] == [NSNull null])
            {
                cell.itemPrice.text = @"$ N/A";
            }
            else
            {
                NSNumberFormatter *currencyStyle = [[NSNumberFormatter alloc] init];
                [currencyStyle setFormatterBehavior:NSNumberFormatterBehavior10_4];
                [currencyStyle setNumberStyle:NSNumberFormatterCurrencyStyle];
                NSNumber *price = [NSNumber numberWithDouble:[[match valueForKey:@"REGULAR"] doubleValue]];
                NSString *stringPrice = [currencyStyle stringFromNumber:price];
                cell.itemPrice.text = [NSString stringWithFormat:@"%@", stringPrice];
            }
            if ([match valueForKey:@"AISLE"] == [NSNull null])
            {
                cell.itemLocation.text = @"Item location: N/A";
            }
            else
            {
                cell.itemLocation.text = [NSString stringWithFormat:@"Item Location: %@", [match valueForKey:@"AISLE"]];
            }
            match = nil;
        }
    }
    return cell;
}

编辑 2: 这是 JSON 的一个片段:

{
    items =     {
        263149 =         {
            AD = "###";
            AISLE = 6A;
            DESCRIPTION = "Cinnamon Toasters";
            R = 9;
            REGULAR = "#.##";
        };
        26599 =         {
            AD = "####";
            AISLE = 6A;
            DESCRIPTION = "Quaker Life Cereal";
            R = 2;
            REGULAR = "#.##";
        };
        40517 =         {
            AD = "###";
            AISLE = 6A;
            DESCRIPTION = "Toasted Oats";
            R = 1;
            REGULAR = "#.##";
        };
    };
}; 
4

2 回答 2

0

好的,我认为您的问题是过度创建 Array 对象。因此,请执行以下操作,而不是创建数组:

NSDictionary *returnArray = [[NSJSONSerialization JSONObjectWithData:itemsData options:kNilOptions error:&error] valueForKey:@"items"];
for (NSDictionary *dict in returnArray in returnArray)
{
    [self.objectsArray addObject:dict];
}
counter += 10;
[itemsTable reloadData];

如您所见,您将得到一个NSDictionary对象数组,您的返回数组已经是一个NSDictionary字典对象。另外,稍微观察一下,你在哪里重置你的计数器?

编辑:创建NSDictionaryfrom NSData

[NSJSONSerialization JSONObjectWithData:self.requestData options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:&error]

requestData 是使用这些委托方法生成的:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
  NSLog(@"In didReceiveResponse");
  [self.requestData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
  NSLog(@"In didReceiveData");
  [self.requestData appendData:data];
}
于 2012-09-26T20:03:12.313 回答
0

我能够在cellForRowAtIndexPath:. 我注释掉:cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];在顶部并确保它只被调用一次。我也按照 8vius 的建议做了一些清理工作,现在只有一次 NSString 在该方法调用中被分配。一旦我做了这两件事,它就很好而且反应灵敏,没有任何口吃。

于 2012-10-01T18:58:12.250 回答