gpt4 book ai didi

ios - NSMutableAttributedString initWithData : causing EXC_BAD_ACCESS on rotation

转载 作者:技术小花猫 更新时间:2023-10-29 10:25:52 29 4
gpt4 key购买 nike

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

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

除了我旋转屏幕时,一切都完美无缺 => 我每次都遇到 exc_bad_access。

使用 Instruments/Zombies,我已经找到了错误,实际上是这个 initWithData:

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

知道为什么吗?

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


仪器/僵尸截图: enter image description here


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 和旋转方法进行一些调试,以查看发生了什么。

另一篇相关文档如下:

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).

Source

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

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com