使用其他方法为 cellForRowAtIndexPath 创建一个数组
Posted
技术标签:
【中文标题】使用其他方法为 cellForRowAtIndexPath 创建一个数组【英文标题】:Creating an Array for cellForRowAtIndexPath with Other Methods 【发布时间】:2014-06-29 01:34:13 【问题描述】:我有一个已编入索引的tableView
,它显示了用户 iPod 库中的歌曲列表。这是我目前获取歌曲标题的方式,这导致滚动非常慢:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
cell.textLabel.text= [self titleForRow:indexPath]; //getting cell content
...调用这些方法:
-(NSString *)titleForRow:(NSIndexPath *)indexpath
NSMutableArray* rowArray=[[NSMutableArray alloc]initWithCapacity:0];
rowArray=[self getArrayOfRowsForSection:indexpath.section];
NSString *titleToBeDisplayed=[rowArray objectAtIndex:indexpath.row];
return titleToBeDisplayed;
-(NSMutableArray *)getArrayOfRowsForSection:(NSInteger)section
NSString *rowTitle;
NSString *sectionTitle;
NSMutableArray *rowContainer=[[NSMutableArray alloc]initWithCapacity:0];
for (int i=0; i<self.alphabetArray.count; i++)
if (section==i) // check for right section
sectionTitle= [self.alphabetArray objectAtIndex:i]; //getting section title
for (MPMediaItem *song in songs)
NSString *title = [song valueForProperty:MPMediaItemPropertyTitle];
rowTitle= [title substringToIndex:1]; //modifying the statement to its first alphabet
if ([rowTitle isEqualToString:sectionTitle]) //checking if modified statement is same as section title
[rowContainer addObject:title]; //adding the row contents of a particular section in array
return rowContainer;
问题是:对于每个cellForRowAtIndexPath
,我正在调用这些方法并为每个单元格创建这些数组。所以我需要创建一个单独的数组并简单地从该数组中调用objectAtIndex
。
这是我迄今为止尝试过的:创建了一个NSMutableArray *newArray
,以及以下方法:
-(NSMutableArray *)getNewArray:(NSInteger)section
NSString *rowTitle;
NSString *sectionTitle;
for (int i=0; i<self.alphabetArray.count; i++)
if (section==i) // check for right section
sectionTitle= [self.alphabetArray objectAtIndex:i]; //getting section title
for (MPMediaItem *song in songs)
NSString *title = [song valueForProperty:MPMediaItemPropertyTitle];
rowTitle= [title substringToIndex:1]; //modifying the statement to its first alphabet
if ([rowTitle isEqualToString:sectionTitle]) //checking if modified statement is same as section title
[newArray addObject:title]; //adding the row contents of a particular section in array
return newArray;
但这似乎非常错误,我真的很困惑如何解决这个问题。我不知道如何用这些方法创建一个单独的数组,用歌曲标题填充newArray
,我已经在谷歌搜索了很长一段时间,但找不到任何对我有帮助的东西。
谁能指出我正确的方向,或者请告诉我如何创建 newArray? I've attached my tableView data source here。谢谢。任何帮助将不胜感激。
【问题讨论】:
你能添加你的数据源的样子吗(你的字母数组)。您有很多代码看起来像是在搜索您的数据源并创建一个新的数据源,所有这些都是为了创建一个单元格。清理它会有很大帮助。 【参考方案1】:表格视图单元格以串行方式入队和出队。利用这种能力,您应该期望只有部分的变化频率较低。您可以使用静态变量来免除部分的提取。看我的代码
-(NSString *)titleForRow:(NSIndexPath *)indexpath
static NSIndexPath *funIndexPath;
static NSMutableArray *funSectionArray;
if (!funIndexPath || funIdexpath.section != indexpath.section)
funIndexPath = indexpath;
funSectionArray = [self getArrayOfRowsForSection:indexpath.section];
rowArray = funSectionArray;
NSString *titleToBeDisplayed = [rowArray objectAtIndex:indexpath.row];
return titleToBeDisplayed;
这是第一个可能的优化。
当我查看您的获取结果数组时,有些事情并不清楚。你为什么要反复检查section == i
。您可以在代码中将section
替换为i
。
-(NSMutableArray *)getNewArray:(NSInteger)section
NSString *rowTitle;
NSString *sectionTitle;
sectionTitle = [self.alphabetArray objectAtIndex:section]; //getting section title
for (MPMediaItem *song in songs)
NSString *title = [song valueForProperty:MPMediaItemPropertyTitle];
rowTitle= [title substringToIndex:1]; //modifying the statement to its first alphabet
if ([rowTitle isEqualToString:sectionTitle]) //checking if modified statement is same as section title
[newArray addObject:title]; //adding the row contents of a particular section in array
return newArray;
目前还不清楚您要在这里实现什么。
与我自己的答案相反,我建议您不要在视图渲染期间计算数据以供显示。您需要尽快创建单元格。为什么不创建一个属性或 iVar(如 @bauerMusic 建议)并计算 viewDidLoad
中的日期或声明一个自定义函数,该函数将重新加载您的属性(可能是 Array
或 Dictionary
)并在渲染 UI 时,只需设置值(在你viewForIndexPath
)?
您可以使用具有两级深度的数组来存储用于维护部分和行。即第 1 级 - 行的部分和数组,第 2 级 - 行。
【讨论】:
感谢您帮助我。在getNewArray
中,我试图创建一个包含所有歌曲标题的新数组,因此我只能加载一次,然后简单地引用cellForRow
中的单个数组。我很抱歉不清楚。当我评论 Hot Licks 和 bauerMusic 的答案时,我对如何使用这些方法创建歌曲标题并将其添加到 @property NSMutableDictionary 感到困惑。 :S【参考方案2】:
这一切的中心是:
cell.textLabel.text = [self titleForRow:indexPath];
现在,您实际使用的是NSString
。简单的。相反,您每次调用都为每个单元格创建一个新数组?
为什么没有一个数组,比如 NSMutableArray。将其作为 @property
或本地 iVar。
@property (strong, nonatomic) NSMutableArray *rowArray;
// Instantiate in -viewDidLoad
rowArray = [NSMutableArray array]; // Much more elegant IMHO
现在调用一个方法来完成所有内容的加载,但要执行 ONCE。您可以随时再次调用它来刷新。
类似:
// In -viewDidLoad
rowArray = [NSMutableArray array];
[self loadArrayContent];
那么,您的 cellForRowAtIndexPath
应该只使用您预加载的 rowArray
并简单地从中提取 NSString
标题。
【讨论】:
感谢您的回答,看看 Hot Licks 的回答,我或许应该将此信息添加到 @property NSMutableDictionary 中。我该怎么做?这实际上是我最初的问题,但我绝对不清楚(我道歉)。我试图在我的getNewArray
方法中添加所有歌曲标题,但它失败了。如何使用这些方法将所有标题添加到@property NSMutableDictionary
,以便保留我的索引? :S
存在一些概念上的差异,但重要的是要注意您仍然需要一个Array
,只是该数组在NSDictionary
中。有一个字面快捷方式@@"key":@"value"
,否则使用setObject:forKey:
。例如:[myDictionary setObject:myArray forKey:@"Song List"];
这是完整的参考:developer.apple.com/library/mac/documentation/Cocoa/Reference/…【参考方案3】:
我处理表视图的一般方法是(在表视图设置期间)为行(锚定在数据源对象中)创建 NSMutableArray。数组中的每个条目都是一个 NSMutableDictionary,它使用该行的基本内容“启动”,如果需要开发更多信息来显示该行,则缓存在字典中。 (如果有多个部分,我使用包含行数组的部分数组。)
我可能对播放列表做的是用空字典初始化数组,然后在滚动时访问每个播放列表元素并将其缓存在字典中。
事实上,如果真的需要,可以通过后台任务(使用适当的锁定)来更新字典,这样滚动速度就不会受到查找操作的阻碍。
【讨论】:
感谢您的回答,我最初的问题有点不清楚,因为我在询问如何将所有标题实际添加到新数组中,因为我试图在我的 OP 中的getNewArray
中这样做,但它发生了可怕的错误。我如何使用这些方法将所有歌曲标题添加到@property NSMutableDictionary
。 :S
@user3127576 -- 创建一个 NSMutableArray。使用 NSMutableDictionary (正如我上面建议的那样)或 NSNull (plain-Jane 版本)对象填充它,使其大小合适。在引用每一行时更新数组。很容易测试给定的数组元素是否已经更新。以上是关于使用其他方法为 cellForRowAtIndexPath 创建一个数组的主要内容,如果未能解决你的问题,请参考以下文章
使用 UIRefreshControl 刷新 UITableView
解析的提要在 UITableView 上不可见,cellForRowAtIndexPath 方法未被访问