本文介绍了NSMutableAttributedString initWithData:在旋转时导致EXC_BAD_ACCESS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 tableview 中显示不同类型的内容,并在 heightForRowAtIndexPath

I display different types of contents in a tableview and calculate the height of each cell using different custom methods, in heightForRowAtIndexPath.

其中一种自定义方法意味着在 NSMutableAttributedString 中转换一些html,然后计算高度这个 NSMutableAttributedString

对于html转换,我使用新的 initWithData:方法。

One of these custom methods implies converting some html in an NSMutableAttributedString, and then calculating the height of this NSMutableAttributedString.
For html conversion I use the new initWithData: method.

所有工作都很完美,除非我旋转屏幕=>我每次都有一个exc_bad_access。

All works perfectly except when I rotate the screen => I've got an exc_bad_access every time.

使用Instruments /僵尸,我已经能够找到错误,事实上这是 initWithData:

Using Instruments / Zombies, I've been able lo locate the error, and in fact it's this initWithData:.

(当我删除了这个方法并使用 initWithString 创建了一个简单的 NSMutableAttributedString ,我可以根据需要多次更改方向,再没有崩溃

(When I remove this method and create a "simple" NSMutableAttributedString with initWithString, I can change orientation as many time as I want, no crash anymore).

知道为什么吗?

(顺便说一下,我的亲ject使用ARC)

(By the way, my project use ARC)

乐器/僵尸截图:

Instrument / Zombie screenshot :

自定义方法在 heightForRowAtIndexPath

< UtilitiesForFrontEndUI heightForFacebookAttributedText :>

< UtilitiesForFrontEndUI 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的自定义方法for html to NSMutableAttributedString conversion:


Custom method using the initWithData for html to NSMutableAttributedString conversion :

< UtilitiesForFrontEndUI formatRawFacebookContentForFrontEndRichTextContents:>

< UtilitiesForFrontEndUI 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

If I replace initWithData by a simple initWithString no more 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;
}


推荐答案

我遇到类似的情况在我的应用程序中。

I have a similar situation happening in my app.

[NSMutableAttributedString initWithData:] 可能需要很长时间才能返回,特别是对于大输入。我的猜测是,当这个调用正在执行时,UIKit旋转处理代码需要运行,但是,由于你的主线程停留在initWithData:调用上,所以事情变得有点紧张。

[NSMutableAttributedString initWithData:] can take a very long time to return, especially for large inputs. My guess is, while this call is executing, the UIKit rotation handling code needs to run, but, since your main thread is stuck on the initWithData: call, things go a little out of whack.

尝试将解析调用从主线程移开,以便它不会阻止它:

Try moving the parsing call away from the main thread, so that it doesn't block it:

+(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 和旋转方法进行一些调试才能看到发生了什么。

It's also possible that, while your rotation is happening, some object related to your method is being deallocated, causing the EXC_BAD_ACCESS. You'll have to do some debugging on the - (void)dealloc and rotation methods to see what is going on.

另一篇相关文档如下:

这篇关于NSMutableAttributedString initWithData:在旋转时导致EXC_BAD_ACCESS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-19 00:34