NSMutableAttributedString initWithData:在旋转时导致EXC_BAD_ACCESS [英] NSMutableAttributedString initWithData: causing EXC_BAD_ACCESS on rotation

查看:383
本文介绍了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.

另一篇相关文档如下:


多核注意事项:自OS X v10.4起,NSAttributedString具有
使用WebKit进行HTML文档的所有导入(但不导出)。
因为WebKit文档加载不是线程安全的,所以这不是
在后台线程上使用是安全的。对于在OS X
v10.5及更高版本上链接的应用程序,如果NSAttributedString在主线程的任何
上导入HTML文档,则通过performSelectorOnMainThread:withObject将WebKit的使用转移到主
线程:waitUntilDone :.这个
使操作线程安全,但它要求主线程
在一种常见模式下执行运行循环。可以通过将标准用户默认值
NSRunWebKitOnAppKitThread的值设置为YES(以获取新行为
而不管链接)或NO(无论是否获取旧行为)来覆盖此行为

链接)。

Multicore considerations: Since OS X v10.4, NSAttributedString has used WebKit for all import (but not for export) of HTML documents. Because WebKit document loading is not thread safe, this has not been safe to use on background threads. For applications linked on OS X v10.5 and later, if NSAttributedString imports HTML documents on any but the main thread, the use of WebKit is transferred to the main thread via performSelectorOnMainThread:withObject:waitUntilDone:. This makes the operation thread safe, but it requires that the main thread be executing the run loop in one of the common modes. This behavior can be overridden by setting the value of the standard user default NSRunWebKitOnAppKitThread to either YES (to obtain the new behavior regardless of linkage) or NO (to obtain the old behavior regardless of linkage).

来源

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

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