我在tableview中显示不同类型的内容,并在heightForRowAtIndexPath中使用不同的自定义方法计算每个单元格的高度。

这些自定义方法之一意味着将某些html转换为NSMutableAttributedString,然后计算此NSMutableAttributedString的高度。
对于html转换,我使用了新的initWithData:方法。

除非我旋转屏幕=>每次我都有一个exc_bad_access,否则所有其他功能都可以正常运行。

使用Instruments/Zombies,我已经能够找到错误,而实际上是initWithData:

(当我删除此方法并使用NSMutableAttributedString创建一个“简单”的initWithString时,我可以根据需要多次更改方向,不再需要crash了)。

知道为什么吗?

(顺便说一句,我的项目使用ARC)

乐器/僵尸截图:


heightForRowAtIndexPath中调用的自定义方法:

heightForFacebookAttributedText:>

+(CGFloat)heightForFacebookAttributedText:(NSString *)attributedText withWidth:(CGFloat)width
{
    NSAttributedString *formatedText = [self formatRawFacebookContentForFrontEndRichTextContents:attributedText];
    CGRect rect= [formatedText boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil];
    return ceilf(rect.size.height);
}

使用initWithData进行HTML到NSMutableAttributedString转换的自定义方法:

formatRawFacebookContentForFrontEndRichTextContents:>
+(NSAttributedString *)formatRawFacebookContentForFrontEndRichTextContents:(NSString *)stringToFormat
{
    // THIS GENERATE EXC_BAD_ACCESS ON DEVICE ROTATION (WORKS IF NO ROTATION)
    NSData *dataContent = [stringToFormat dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableAttributedString *richTxtContent = [[NSMutableAttributedString alloc] initWithData:dataContent options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]} documentAttributes:nil error:nil];

    NSRange myRange;
    myRange.location = 0;
    myRange.length = richTxtContent.length;

    [richTxtContent addAttributes:[self commonAttributesForFrontEndRichText] range:myRange];

    return richTxtContent;
}

如果我用一个简单的initWithString代替initWithData,就不再需要exc_bad_access
+(NSAttributedString *)formatRawFacebookContentForFrontEndRichTextContents:(NSString *)stringToFormat
{
    // THIS WORKS (NO MORE ROTATION CRASH)
    NSMutableAttributedString *richTxtContent = [[NSMutableAttributedString alloc]initWithString:stringToFormat];

    NSRange myRange;
    myRange.location = 0;
    myRange.length = richTxtContent.length;

    [richTxtContent addAttributes:[self commonAttributesForFrontEndRichText] range:myRange];

    return richTxtContent;
}

最佳答案

我的应用程序中也发生了类似的情况。
[NSMutableAttributedString initWithData:]可能需要很长的时间才能返回,尤其是对于大型输入。我的猜测是,在执行此调用的同时,需要运行UIKit旋转处理代码,但是,由于您的主线程停留在initWithData:调用上,因此事情有些不合时宜了。

尝试将解析调用从主线程中移开,以免其阻塞:

+(NSAttributedString *)formatRawFacebookContentForFrontEndRichTextContents:(NSString *)stringToFormat completion:(void (^)(NSAttributedString *))completion
   {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
                NSData *dataContent = [stringToFormat dataUsingEncoding:NSUTF8StringEncoding];
                NSMutableAttributedString *richTxtContent = [[NSMutableAttributedString alloc] initWithData:dataContent options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]} documentAttributes:nil error:nil];

                NSRange myRange;
                myRange.location = 0;
                myRange.length = richTxtContent.length;

                [richTxtContent addAttributes:[self commonAttributesForFrontEndRichText] range:myRange];

                 dispatch_async(dispatch_get_main_queue(), ^{
                      if (completion)
                          completion(richTxtContent);
                 })
            });
    }

当旋转发生时,与方法相关的某些对象也可能被释放,从而导致EXC_BAD_ACCESS。您必须对- (void)dealloc和rotation方法进行一些调试,以查看发生了什么。

另一个相关文档如下:



Source

关于ios - NSMutableAttributedString initWithData : causing EXC_BAD_ACCESS on rotation,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20730326/

10-10 11:52