我有一个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 = "#.##";
};
};
};
答案 0 :(得分: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
个字典对象。另外,稍微观察一下,你在哪里重置你的柜台?
编辑:从NSDictionary
创建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];
}
答案 1 :(得分:0)
我能够在cellForRowAtIndexPath:
的一行中找到问题。我在顶部注释掉了cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
并确保它只被调用一次。我也按照8vius的建议进行了一些清理工作,现在只在该方法调用中分配了NSString。一旦我完成了这两件事,它就会很好并且在没有任何口吃的情况下再次响应。