1

私は、最初の iOS プロジェクトに取り組んでいる Android 開発者です。ほぼ 37,500 行を表示する UITableView があります。食料品店の商品ごとに 1 行。リストには 3 つの列があり、1 つはアイテム名を含み、他の 2 つはその他の重要なデータを含みます。列は並べ替え可能で、並べ替えを処理するために必要に応じてデータ配列を並べ替え、配列の[tableView reloadData]並べ替えが完了したら呼び出します。これは正常に機能しますが、メイン スレッドが作業中にロックされているデータをリロードした後、少なくとも数秒の長い遅延が発生します。Android で何度もスムーズなリストを作成する必要があったため、リストのパフォーマンスについてはよく知っています。だから私が言えることから、私はこれを引き起こすために実際に多くのことをしていません. 考えられる唯一のことは、配列内の多数のアイテムだけです。関連するコードは次のとおりです。

私がオーバーライドしているテーブルメソッドは次のとおりです。

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
     return [self.data count];
 }

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"CustomCell";
ReplenishListCell *cell = [self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

if (cell == nil) {
    cell = [[ReplenishListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}

NSMutableDictionary *dictData = [self.data objectAtIndex:indexPath.row];

cell.nameLabel.text = dictData[@"item-description"];
cell.firstLicationColumnLabel.text = dictData[@"store-count"];
cell.secondLicationColumnLabel.text = dictData[@"other-count"];

return cell;
}

-(void)tableView:(UITableView *)replenishTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self showActivityIndicator];

ReplenishListCell *cell = (ReplenishListCell*) [replenishTableView cellForRowAtIndexPath:indexPath];
NSString *nameClicked = cell.nameLabel.text;

[database getItemByName:nameClicked :self];
}

配列をソートするために使用する方法は次のとおりです。

-(void) sortArray:(NSString *) dictionaryKey {
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:dictionaryKey ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
NSArray *sortedArray = [data sortedArrayUsingDescriptors:sortDescriptors];

[data removeAllObjects];
[data addObjectsFromArray:sortedArray];

[self.tableView reloadData];
}

を呼び出すまで、パフォーマンスの問題はありません[self.tableView reloadData]。それで、私が欠けているものがあるかどうか疑問に思っていますか、それともデータをリロードするより良い方法がありreloadDataますか?どんな助けでも大歓迎です。デバッグとグーグルで数時間を費やしましたが、まだ解決策が思い浮かびません。

4

3 に答える 3

1

大規模な操作の場合は、メイン キューで実行して UI をブロックするのではなく、バックグラウンド キューを使用する必要があります。バックグラウンド操作からデータが利用可能になった後、メイン キューで reloadData を呼び出すことができます。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
            [self sortArray:<# your key #>];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    });
});

前の回答のように、ポールの提案を使用することも検討してください。

于 2013-11-12T21:44:30.680 に答える
1

UI がハングする原因の 1 つとして、2 つの配列間で 37.5k オブジェクトをすべて削除および追加していることが考えられます。

これを変更してみてください:

[data removeAllObjects];  
[data addObjectsFromArray:sortedArray];

これに:

data = sortedArray;
于 2013-11-12T21:36:31.817 に答える
1

あなたのコードはよさそうです。@paulrehkuglerが彼の答えで言っているdata = sortedArrayように、配列をソートするだけで済みます。

持っているデータの量を考慮して、バックグラウンド スレッドでデータを事前に並べ替えることを検討してください。私の計算では、37,500 個のオブジェクトで、並べ替え順序が異なる約 3 つの配列を保持すると、150K のメモリが必要になります。したがって、ユーザーが特定の列で並べ替えることを選択した場合、データは既に並べ替えられており、データ ソースとして使用される配列を交換するだけです。ユーザーにとって、並べ替えは実​​質的に瞬時に行われるように見えます。

于 2013-11-12T21:46:25.183 に答える