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

前端之家收集整理的这篇文章主要介绍了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 *检测器初始化为静态而不是初始化它为每个单元格提高性能.

猜你在找的iOS相关文章