微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

iOS 7 UITextView中的UITextView链接检测崩溃

我有一个定制的UITableView单元格设置在我的UITableView像这样:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static Nsstring *identifier = @"CELL_IDENTIFIER";

    SGCustomCell *cell = (SGCustomCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
    if (!cell) cell = [[SGCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];

    cell = [self customizedCell:cell withPost:[postsArray objectAtIndex:indexPath.row]];

    return cell;
}

我设置了这样的单元格(具体设置UITextView.text为零 – 如this answer所述):

descriptionLabel.text = nil;
descriptionLabel.text = post.postDescription;

descriptionLabel.frame = CGRectMake(leftMargin - 4,currentTitleLabel.frame.origin.y + currentTitleLabel.frame.size.height + 10,self.frame.size.width - topMargin * 3,100);
[descriptionLabel sizetoFit];

这些单元格是100%可重用的,UITextView是这样的(如你所见,没有什么特别的):

descriptionLabel = [[UITextView alloc] init];
descriptionLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:11];
descriptionLabel.editable = NO;
descriptionLabel.scrollEnabled = NO;
descriptionLabel.dataDetectorTypes = UIDataDetectorTypeLink;
descriptionLabel.frame = CGRectMake(leftMargin,10);
[self addSubview:descriptionLabel];

但是当桌子有大约50个单元格,当我滚动它,我得到以下崩溃:

Terminating app due to uncaught exception 'NSRangeException',reason: 'NSMutableRLEArray objectAtIndex:effectiveRange:: Out of bounds'

这是绝对可笑的 – 我注释掉这一行 – descriptionLabel.dataDetectorTypes = UIDataDetectorTypeLink;并且应用程序停止崩溃!我花了几个小时试图弄清楚问题是什么,现在我只是得到这个.

在iOS 7.0.3上测试

解决方法

当具有数据类型的两个单元格正在出队时,发生崩溃
使用相同的单元格标识符.
这似乎是iOS中的一个bug,但是苹果可能有很好的理由来实现它.
(记忆聪明)

因此,唯一的100%防弹解决方案是为单元格提供唯一的标识符
包含数据类型.
这并不意味着您将为表格中的所有单元格设置唯一的标识符,当然,
因为它会吃掉太多的记忆,你的桌面滚动将会很慢.

您可以使用NSDataDetector来确定文本中是否找到匹配的类型,
然后只将发现的对象作为单元格标识符保存,如下所示:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    Nsstring *row = [self.dataSource objectAtIndex:indexPath.row];
    static NSDataDetector *detector = nil;
    if (!detector)
    {
        NSError *error = NULL;
        detector = [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink | NSTextCheckingTypePhoneNumber error:&error];
    }

    NSTextCheckingResult *firstDataType = [detector firstMatchInString:row
                                                               options:0
                                                                 range:NSMakeRange(0,[row length])];
    Nsstring *dataTypeIdentifier = @"0";
    if (firstDataType)
    {
        if (firstDataType.resultType == NSTextCheckingTypeLink)
            dataTypeIdentifier = [(NSURL *)[firstDataType URL] absoluteString];
        else if (firstDataType.resultType == NSTextCheckingTypePhoneNumber)
            dataTypeIdentifier = [firstDataType phoneNumber];
    }

    Nsstring *CellIdentifier = [Nsstring stringWithFormat:@"Cell_%@",dataTypeIdentifier];

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
...

注意:将NSDataDetector *检测器初始化为静态而不是初始化它为每个单元格提高性能.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐