美文网首页iOS开发iOS 坑的集中营iOS 开发
TableView 通过registerClass: forCe

TableView 通过registerClass: forCe

作者: 踩坑小分队 | 来源:发表于2016-09-30 15:15 被阅读1960次

    tableView是经常使用的控件之一,有了tableView就离不开cell。一般cell的使用都是复用使用的,
    cell的加载经常使用的有两种方法,一种就是直接如下方法去获取cell

    #pragma mark- UITableViewDataSource
    - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
    {
    staticNSString*identifier =@"MyTableViewCell";
    MyTableViewCell*cell = [tableViewdequeueReusableCellWithIdentifier:identifier ];
    if(!cell) {
    cell = [[MyTableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:identifier];
    }
    returncell;
    }
    

    另外一种是通过registerClass: forCellReuseIdentifier:把tableView和cell联系在一块

    - (UITableView*)myTableView
    {
    if(!_myTableView) {
    UITableView* myTableView = [[UITableViewalloc]initWithFrame:self.view.framestyle:UITableViewStylePlain];
    myTableView.delegate=self;
    myTableView.dataSource=self;
    //注册cell
    [myTableView registerClass:[MyTableViewCellclass] forCellReuseIdentifier:@"MyTableViewCell"];
    //或者这么注册
    //[myTableView registerNib:[UINib nibWithNibName:@"MyTableViewCell" bundle:nil] forCellReuseIdentifier:@"MyTableViewCell"];
    _myTableView= myTableView;
    }
    return_myTableView;
    }
    
    #pragma mark- UITableViewDataSource
    - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
    {
    MyTableViewCell*cell = [tableViewdequeueReusableCellWithIdentifier:@"MyTableViewCell"forIndexPath:indexPath];
    returncell;
    }
    

    最近遇见一个奇葩的事情,可能有点绕,一点点来吧。说一下这个第二种加载cell的方式,
    一般在注册cell的时候<registerClass: forCellReuseIdentifier:或者registerNib: forCellReuseIdentifier:>的同时会去设置下tableView的相关的属性,比如设置一下分割线的样式之类的。
    代码如下

    - (UITableView*)myTableView
    {
    if(!_myTableView) {
    UITableView* myTableView = [[UITableViewalloc]initWithFrame:self.view.framestyle:UITableViewStylePlain];
    myTableView.delegate=self;
    myTableView.dataSource=self;
    myTableView.tableFooterView= [UIViewnew];
    myTableView.separatorStyle=UITableViewCellSeparatorStyleNone;
    [myTableViewregisterClass:[MyTableViewCellclass]forCellReuseIdentifier:@"MyTableViewCell"];
    _myTableView= myTableView;
    }
    return_myTableView;
    }
    
    - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
    {
    MyTableViewCell*cell = [tableViewdequeueReusableCellWithIdentifier:@"MyTableViewCell"forIndexPath:indexPath];
    returncell;
    }
    

    iOS8.4真机,一运行,发现崩溃了。ps:使用了8.0,8.4,9.0,10.0运行,8.0,8.4运行都崩溃了,其他的系统没有问题,能够正常运行。报错信息如下,顿时感觉就不好了。
    *** Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit/UIKit-3347.44.2/UITableView.m:6245

    然后进行代码调试发现如下蛋疼的规律,针对iOS8系统

    myTableView.tableFooterView= [UIViewnew];
    myTableView.separatorStyle=UITableViewCellSeparatorStyleNone;
    [myTableViewregisterClass:[MyTableViewCellclass]forCellReuseIdentifier:@"MyTableViewCell"];
    

    这三行代码不能这么写,如果顺序是当前顺序,并且myTableView.separatorStyle=UITableViewCellSeparatorStyleNone,
    或者tableview的style = UITableViewStyleGrouped并且myTableView.separatorStyle=UITableViewCellSeparatorStyleSingleLineEtched,会崩溃。其他的情况均没有问题。

    其他情况包括:
    1、这三行代码的顺序不是这个顺序,随机组合。假设三句代码的顺序是1,2,3
    除了1,2,3会崩溃意外,其他的顺序都不会崩溃<1,3,2 3,1,2 3,2,1.......>

    2、是当前的顺序,但是myTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine

    3、当前顺序删除掉myTableView.tableFooterView= [UIViewnew];或者删除掉myTableView.separatorStyle=UITableViewCellSeparatorStyleNone;,或者两句话都删除,都不会报错崩溃。

    这个规律发现的很纠结,也不知道什么原因。针对iOS8。各路大神有遇到的吗?麻烦指点一二
    参考Demo : https://github.com/RunOfTheSnail/TableViewDemo

    相关文章

      网友评论

      • 半边枫叶:我也遇到了,本来还以为是使用到了iOS8不支持的sdk呢,找了半天没有找到原因。看到这篇文章才发现是这里的问题
        浪漫小牛:另外至于为甚iOS10以下才会崩溃,估计是iOS10又坑爹的优化过了
        浪漫小牛:myTableView.tableFooterView= [UIViewnew];
        myTableView.separatorStyle=UITableViewCellSeparatorStyleNone;
        [myTableViewregisterClass:[MyTableViewCellclass]forCellReuseIdentifier:@"MyTableViewCell"];
        最近我也遇到这个问题了,这三句话中崩溃的原因只和第二第三句话有关系,调换以下2和3的顺序就好了,我猜原因如下:注册cell是使cell和tableView进行绑定,重用的时候从tableView里面找,而设置分割线的样式的属性,我猜这个属性内部其实是cell的样式,崩溃的原因是没有注册cell就去设置样式所以会崩溃.以上原因是我估计的,没有具体的依据
        踩坑小分队:@半边枫叶 其实我也没有找到原因,只是实验结果
      • ducks:遇见过 。。。 调换一下分割线必须设置在代理之前
        踩坑小分队:@ducks 试验过了,你说的是对的,但是不知道为啥?还请大神继续指点一二
        踩坑小分队:@ducks 只有ios8会有,是不是苹果的bug,你的情况和我说的一样吗?

      本文标题:TableView 通过registerClass: forCe

      本文链接:https://www.haomeiwen.com/subject/tszlyttx.html