iOS 7 UITextView链接检测崩溃在UITableView [英] iOS 7 UITextView link detection crash in UITableView

查看:385
本文介绍了iOS 7 UITextView链接检测崩溃在UITableView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义 UITableView 单元格设置在我的 UITableView 像这样:

I have a custom UITableView cell set up in my UITableView like this:

- (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 到 nil - 如中所述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 (如你所见,没什么特别的):

The cells are 100% reusable and UITextView is inited like this (as you see, nothing special):

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个单元格时,当我快速滚动我得到以下崩溃:

But when the table has around 50 cells and when I scroll it fast I get the following crash:

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

这是绝对可笑的 - 我注释掉这一行 - descriptionLabel .dataDetectorTypes = UIDataDetectorTypeLink; ,应用程序停止崩溃!

Which is absolutely ridiculous - I comment out this line - descriptionLabel.dataDetectorTypes = UIDataDetectorTypeLink; and the app stops crashing! I've spent hours trying to figure out what the problem was and now I simply get this.

在iOS 7.0.3上测试

Tested on iOS 7.0.3

推荐答案

我一直在调查这个问题很久了。
解决此问题的所有尝试失败!
包括prepareForUse中建议的修复程序或
设置dataDetectorTypes的开启和关闭。

I've been investigating this issue for long time now. All attempts to workaround this issue failed! including the suggested fix in prepareForUse or setting the dataDetectorTypes on and off.

崩溃发生在两个有数据类型的单元出队时
使用相同的单元标识符。
这似乎是一个在iOS中的错误,但苹果可能有很好的理由实现它的方式。
(记忆力)

The crash happens when two cells with data type are being dequeued while using the same cell identifier. It seems to be a bug in iOS, but Apple may have good reasons to implement it this way. (memory wise)

因此,唯一的100%防弹解决方案是为包含数据类型的单元
提供一个唯一的标识符。
这并不意味着你将为你的表中的所有单元格设置一个唯一的标识符,当然,
,因为它会占用太多的内存,你的表滚动会很慢。

And so the only 100% bullet proof solution is to provide a unique identifier for cells containing data types. This doesn't mean you will set a unique identifier to all cells in your table, of course, as it will eat up too much memory and your table scroll will be really slow.

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

You can use NSDataDetector to determine if a matched type was found on your text, and only then save the found object as the cell identifier, like so:

- (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 *检测器初始化为静态
,而不是为每个单元初始化它提高性能。

Note: Initializing NSDataDetector *detector as static rather than initialize it for each cell improves performance.

这篇关于iOS 7 UITextView链接检测崩溃在UITableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆