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

2023-11-22

我有一个习惯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 to nil- 如中所述这个答案):

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, currentTitleLabel.frame.origin.y + currentTitleLabel.frame.size.height + 10, self.frame.size.width - topMargin * 3, 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 中的一个错误,但苹果可能有充分的理由以这种方式实现它。 (记忆力)

因此,唯一 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 *Detector 初始化为静态 而不是为每个单元初始化它可以提高性能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS 7 UITableView 中的 UITextView 链接检测崩溃 的相关文章

随机推荐