【发布时间】:2016-12-11 09:04:19
【问题描述】:
我有一个独特的案例,我需要使用来自 sqlite 数据库的数千个项目填充菜单...
我目前正在使用以下代码填充它,但它在填充时阻塞了主线程,并且在填充约 3000 个项目时需要一分钟以上的时间来加载(第一次)。有没有一种有效的方法可以在不阻塞 ui 的情况下以较小的块延迟加载菜单?
规则.h
{
IBOutlet NSPopUpButton *rulesSelectionButton;
}
@property (retain) IBOutlet NSPopUpButton *rulesSelectionButton;
规则.m
@synthesize rulesSelectionButton;
以及填充按钮的代码:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *selected = [defaults objectForKey:rulesSelectionString];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *path = [dbPath stringByExpandingTildeInPath];
__block NSArray *final = [NSArray new];
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];
[queue inDatabase:^(FMDatabase *db) {
FMResultSet *results = [db executeQuery:@"SELECT * FROM rules"];
NSMutableArray *array = [NSMutableArray new];
[array addObject:NSLocalizedString(@"Random...", nil)];
while ([results next]) {
@autoreleasepool {
NSString *title = [NSString stringWithFormat:@"%@ (%@)", [results stringForColumn:@"Organization_Rules"], [results stringForColumn:@"Assignment"]];
[array addObject:title];
}
}
final = [[NSSet setWithArray:array] allObjects];
}];
NSArray *sortedKeys = [final sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
dispatch_async(dispatch_get_main_queue(), ^{
[rulesSelectionButton removeAllItems];
[rulesSelectionButton addItemsWithTitles:sortedKeys];
[rulesSelectionButton selectItemWithTitle:selected];
});
});
【问题讨论】:
-
我在您的代码中没有看到一个单词“NSPopUpButton”。无论如何,创建数千个菜单项是个坏主意。
-
rulesSelectionButton 是一个属性,我添加了相关代码。将数千个菜单项放入一个菜单可能是个坏主意,但我仍然需要这样做,因为它是最好的方法呈现数据。
-
我不认为这是呈现数据的最佳方式,因为 NSPopUpButton 的设计目的不是处理数千个项目。苹果表示:“使用弹出菜单来呈现多达 12 个互斥选项,用户不需要一直看到这些选项。”和“考虑对大量项目使用滚动列表,而不是弹出菜单。”
-
谢谢大家,我发现 NSComboBox 可以满足我的所有需求,而且加载速度非常快。 :)