从 8000 个项目列表中加载 NSComboBox 的最快方法

Posted

技术标签:

【中文标题】从 8000 个项目列表中加载 NSComboBox 的最快方法【英文标题】:Fastest way to load an NSComboBox from an 8000 item plist 【发布时间】:2013-08-12 06:09:05 【问题描述】:

我有一个 plist,基本上是 8000 个用户名的列表。我将它加载到一个 NSDictionary 中,然后是一个排序键数组(因为我得到它时列表没有排序),然后循环加载到一个 NSComboBox 中。

这可行,但可能需要几秒钟来填充组合框。

这是我的代码:

// in my .h
IBOutlet NSComboBox *comboUserList; // which is connected to a combo box in my .xib

// in my .m

// userInfoPlist is an NSString path to the file
NSDictionary *userList = [NSDictionary dictionaryWithContentsOfFile:userInfoPlist];

// sort user info into an array

NSArray* sortedKeys = [userList keysSortedByValueUsingSelector:@selector(caseInsensitiveCompare:)];

// then populate the combo box from userList in the order specified by sortedKeys

for ( NSString *usersKey in sortedKeys) 
    [comboUserList addItemWithObjectValue:[userList objectForKey:usersKey]];

所以这是可行的,但是对于 8000 个奇数条目,填充组合框需要一些明显的时间(在 2011 年的 MACBook Air 上只需一两秒,但仍然很明显)。有没有更快的方法来使用 NSDictionary 或 NSArray 作为数据源,而不是在 for 循环中执行?

【问题讨论】:

【参考方案1】:

用户外部数据源。

[mEmailListBox setUsesDataSource:YES];
[mEmailListBox setDataSource:self];  
/*
If you use setDataSource: before setUsesDataSource:, setDataSource: throws an exception.
*/
- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox;

    return [DatSource count];//DatSource NSArray

- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index;

    return DatSource[index];
  

看看Combo Box Programming Topics

您还可以借助noteNumberOfItemsChangedreloadData 方法在后台加载数据

【讨论】:

我以前见过,但它会影响显示顺序吗?据我所知,外部数据源可以工作,但它需要一个编号索引“外部数据源可以以任何方式存储其项目,但它必须能够通过整数索引识别它们。”这意味着重新格式化原始 plist 或者我可以将其导入有序数组(就像我已经做的那样)并将该数组用作数据源? 您可以使用数组作为数据源。【参考方案2】:

您应该使用数据源而不是直接提供值。使用-[NSComboBox setUsesDataSource:]-[NSComboBox setDataSource:] 设置您的数据源,然后在您的控制器上实现NSComboBoxDataSource 协议。

见: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSComboBoxDataSource_Protocol/Reference/Reference.html#//apple_ref/occ/intf/NSComboBoxDataSource

【讨论】:

【参考方案3】:

如果您在对键进行排序并将值放入 NSComboBox 时不需要像此代码这样的行为,您可以采取不同的方式。

如果可以放置排序的键或值,您可以使用一次调用而不是循环:

[comboUserList addItemsWithObjectValues:sortedKeys];

【讨论】:

以上是关于从 8000 个项目列表中加载 NSComboBox 的最快方法的主要内容,如果未能解决你的问题,请参考以下文章

我可以从缓存中加载后退按钮吗?

在一个活动中加载单个片段两次,从本地json文件中加载2个问题

Angular 2 Select - 从 Web 服务问题中加载数据

从数组中加载列表

laravel 新项目未运行仍在浏览器中加载

在 mvc 中加载 2 个下拉列表的更好方法