7

我正在tableView:cellForRowAtIndexPath:从 nib 文件中读取自定义表格单元格。这对我的目的很有用,只是速度很慢。

现在,我知道从长远来看正确的做法是完全在代码中创建单元格,并使用单个视图,等等。但这是一个原型,我不想为此付出太多努力。

现在,如果我在UIViewController子类中只阅读笔尖一次,然后tableView:cellForRowAtIndexPath:复制它,我会很高兴。我在这里的假设是复制会比阅读笔尖更快。

这是我用来加载笔尖的东西,我从viewDidLoad:(和retain之后)调用

-(id)loadFromNamed:(NSString*)name {
    NSArray *objectsInNib = [[NSBundle mainBundle] loadNibNamed:name
                                                          owner:self
                                                        options:nil];
    assert( objectsInNib.count == 1 );
    return [objectsInNib objectAtIndex:0];
}

到目前为止一切都很好。但问题是:我如何一遍又一遍地复制它?甚至可能吗?

我试过[_cachedObject copy][_cachedObject mutableCopy]UITableViewCell支持任何一种复制协议。

如果必须,我可以告诉他们在我准备完全移除笔尖之前忽略速度,但如果这里有一个低垂的果实,我宁愿让它快一点。

有任何想法吗?

4

5 回答 5

8

我认为表格单元格的处理可以与出队机制一起使用,这将允许一次创建单元格(从 nib 或以编程方式或从其他 nib 自动加载并链接为 IB 中的出口)然后克隆它或将其出列需要的时候。

UITableViewCell 不符合 NSCopying 协议,但支持 keyed 归档/取消归档机制,因此可以用于克隆。

基于回答“ 如何在 Objective C 中复制 UIButton? ”我的数据源委托方法如下所示:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellID = @"CellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellID];

    if (!cell) {
        NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:self.tableViewCell];
        cell = [NSKeyedUnarchiver unarchiveObjectWithData:archivedData];
    }

    // ... config ...

    return cell;
}

在我的例子中self.tableViewCell是一个从视图的 nib 文件中加载一次的单元格。

我没有测试什么会更快:克隆“归档+取消归档”或“加载笔尖文件+取消归档”框架在-loadNibNamed:owner:options:的情况下会做什么,我使用这种方法只是为了方便考虑,但是内存操作与文件操作的好机会会更快。

编辑:它似乎并不像起初看起来那么容易。由于 UIImage 不符合 NSCoding,因此配置了 UIImageViews 的单元格不能在没有额外代码的情况下被复制。是的,复制整个图像绝对不是一个好习惯,为苹果指出这一点而欢呼。

于 2011-03-17T12:00:17.693 回答
6

使用表格视图中内置的单元格克隆。Apple 知道生成大量表格单元格的速度很慢。查看此方法的文档:

- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier

您创建一次单元格,然后在请求新单元格时,使用该方法克隆现有单元格。然后,您只需更改新单元格需要更改的内容并返回单元格对象。

另请查看 Apple 提供的使用此方法的 table view realted 示例代码,并向您展示正确的方法。您的细胞是从笔尖加载的这一事实根本不重要。


小澄清:我不认为上述方法为您克隆细胞。相反,它需要滚动离开屏幕的单元格对象并将它们简单地移动到新位置。所以它实际上是在重复使用一个单元格。因此,请确保您的自定义表格视图可以设置为它在初始化之外需要的所有新值。

于 2009-02-20T21:11:32.293 回答
4

对此解决方案并不感到自豪,但它适用于最大数量的可能 IB 绑定:

接口(AlbumTableViewCell 是 UITableViewCell 的子类,其实例在 AlbumViewController 的 XIB 文件中定义):

@interface AlbumsViewController : UITableViewController {
    IBOutlet AlbumTableViewCell *tableViewCellTrack;
}

@property (nonatomic, retain) AlbumTableViewCell *tableViewCellTrack;

实现(取消归档/归档复制/克隆表格视图单元格):

@implementation AlbumsViewController

@synthesize tableViewCellTrack;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    AlbumTableViewCell *cell = (AlbumTableViewCell *)[tableView dequeueReusableCellWithIdentifier: @"AlbumCell"];

    if (cell == nil) {
        AlbumsViewController *albumsViewController = [[[AlbumsViewController alloc] init] autorelease];
        [[NSBundle mainBundle] loadNibNamed: @"AlbumsViewController" owner: albumsViewController options: nil];

        cell = albumsViewController.tableViewCellTrack;
    }

    cell.labelTitle.text = ...;
    cell.labelArtist.text = ...;

    return cell;
}
于 2009-12-08T09:06:04.163 回答
3

好吧,我不确定为什么所有的教程都没有指定这一步。

从 Nib 使用您自己的自定义 UITableViewCell 时,调用 dequeueReusableCellWithIdentifier 是不够的。您必须在 IB 中指定“标识符”,仅在 Table View Cell 选项卡部分中指定。

然后确保您放入 IB 的标识符与您用于 dequeueReusableCellWithIdentifier 的标识符相同。

于 2009-06-17T04:10:23.230 回答
1

这是在斯威夫特

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell : UITableViewCell?
    let cellId = String(format: "Cell%d", indexPath.row)
    cell = alertTable!.dequeueReusableCellWithIdentifier(cellId) as! UITableViewCell?

    if cell == nil {
        let archivedData = NSKeyedArchiver.archivedDataWithRootObject(masterTableCell!)
        cell = NSKeyedUnarchiver.unarchiveObjectWithData(archivedData) as! UITableViewCell?
    }

    // do some stuff

    return cell!
}
于 2015-10-24T02:00:45.860 回答