ios - CTRunDelegateRef iPhone 的内存管理

标签 ios memory core-text

我专注于一个基于OmniGroup的rtf编辑器添加图像支持的项目。我在使用CTFramesetterCreateWithAttributedString时遇到了问题,它收到了

EXC_BAD_ACCESS

这是由僵尸对象引起的。

为简单起见,我从只有一张照片的 rtfd 文件中获取 NSAttributedString。我根据 Omni 的示例添加了在 iOS 上解析图像标签的方法。创建 NSAttributedString 的部分后面是这个 tutorial from raywenderlich ,看起来像:


    CTRunDelegateCallbacks callbacks;
    callbacks.version = kCTRunDelegateCurrentVersion;
    callbacks.getAscent = ascentCallback;
    callbacks.getDescent = descentCallback;
    callbacks.getWidth = widthCallback;
    callbacks.dealloc = deallocCallback;
    CTRunDelegateRef delegate = CTRunDelegateCreate(&callbacks, imgAttr); 

    NSDictionary *imgAttr = [NSDictionary dictionaryWithObjectsAndKeys:imgWidth,kImageWidth,imgHeight,kImageHeight, nil];//recored the width and height
    NSDictionary *attrDictionaryDelegate = [NSDictionary dictionaryWithObjectsAndKeys:(id)delegate, (NSString*)kCTRunDelegateAttributeName,nil];
     [_attributedString appendString:@" " attributes:attrDictionaryDelegate];
     CFRelease(delegate);

这里的appendString:attributes:是Omni提供的,是NSMutableAttributedString的一个类:


- (void)appendString:(NSString *)string attributes:(NSDictionary *)attributes;
{
    NSAttributedString *append;

    append = [[NSAttributedString alloc] initWithString:string attributes:attributes];
    [self appendAttributedString:append];
    [append release];
}

在 Parser 类中,我测试了 CTFramesetterCreateWithAttributedString 并且它创建成功并且没有发生内存问题。但是,当我在我的 View 类中调用 CTFramesetterCreateWithAttributedString 时,它会收到 EXC_BAD_ACESS 问题。我将 CTFramesetterCreateWithAttributedString 发送到我在 viewDidLoad:

中的 View

NSArray *arr = [OUIRTFReader parseRTFString2:rtfString];
self.editFrame.attributedText = [arr objectAtIndex:0];


//for OUIRTFReader
+ (NSArray *)parseRTFString2:(NSString *)rtfString
{
    OUIRTFReader *parser = [[self alloc] _initWithRTFString:rtfString];
    NSMutableArray *temp  = [NSMutableArray arrayWithCapacity:1];
    NSAttributedString *tempAstr = [[NSAttributedString alloc] initWithAttributedString:parser.attributedString];

    [temp addObject:tempAstr];
    [tempAstr release];
    if (parser.zjImageArray) {
        [temp addObject:parser.zjImageArray];
    }

    [parser release];
}

这里的editFrame是OmniFramework提供的OUIEditableFrame的ivar。 之后,在OUIEditableFramelayoutSubview:中,CTFramesetterCreateWithAttributedString失败。使用 instrument 进行分析,它指出 :

中有一个僵尸对象

NSDictionary *imgAttr = [NSDictionary dictionaryWithObjectsAndKeys:imgWidth,kImageWidth,imgHeight,kImageHeight, nil];

证明了

An Objective-C message was sent to a deallocated object(zombie) at address

我不太熟悉 UIKit 或其他核心基础。所以我想知道在我的代码中使用 CTRunDelegateRef 为图像创建属性字符串的方法有什么问题?

谢谢!

最佳答案

CTRunDelegateCreate 使用任意上下文指针 (void *) 创建委托(delegate)。这意味着字典 imgAttr 没有被委托(delegate)保留。

创建delegate时需要保留context字典,在dealloc回调中释放。

关于ios - CTRunDelegateRef iPhone 的内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8558513/

相关文章:

ios - 如何使用核心文本在ios中的不同UIlabel文本行上设置不同的字体样式

iphone - CoreText 映射字符

iphone - CTFrameGetLineOrigins的来源不正确

ios - UITextView 的界面生成器和子类

c++ - 32 位 C++ 程序中的最大可寻址内存空间是多少?

ios - iOS 上的高虚拟内存使用率 + 低分配

c - 动态内存分配。我错过了什么?

ios - IOS 10上的Firebase无法从真实设备上的数据库加载数据

ios - 更换Vuforia中的茶壶

iphone - objective-c : Do I have to retype all the code everytime?