TableView 通过 registerClass: forCellReuseIdentifier: 方法加载 cell,iOS8 奇葩崩溃

1,561 阅读2分钟

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的时候的同时会去设置下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 : github.com/RunOfTheSna…