NSMutableAttributedString initWithData:在旋转时导致EXC_BAD_ACCESS

 手机用户2502860763 发布于 2023-02-08 16:42

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

其中一个自定义方法意味着转换一些html NSMutableAttributedString,然后计算它的高度NSMutableAttributedString.
对于html转换,我使用新initWithData:方法.

一切都很完美,除非我旋转屏幕=>我每次都有一个exc_bad_access.

使用Instruments/Zombies,我已经能够找到错误,事实上就是这样initWithData:.

(当我删除此方法并创建一个"简单" NSMutableAttributedStringinitWithString,我可以根据需要更改方向,crash不再有).

知道为什么吗?

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


Instrument/Zombie截图: 在此输入图像描述


调用的自定义方法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;
}

Arie Litovsk.. 11

我的应用程序中发生了类似的情况.

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

另一篇相关文档如下:

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

资源

1 个回答
  • 我的应用程序中发生了类似的情况.

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

    另一篇相关文档如下:

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

    资源

    2023-02-08 16:44 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有