使用其他方法为 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 中的日期或声明一个自定义函数,该函数将重新加载您的属性(可能是 ArrayDictionary)并在渲染 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 创建一个数组的主要内容,如果未能解决你的问题,请参考以下文章

使用uitextfields创建uitableview表单

使用 UIRefreshControl 刷新 UITableView

解析的提要在 UITableView 上不可见,cellForRowAtIndexPath 方法未被访问

TableViewCell 自动释放错误

自定义 UITableViewCell 的 viewDidLayoutSubviews

为啥 CPU 使用率和线程数会达到 99-100%?