управление памятью для iPhone CTRunDelegateRef - PullRequest
1 голос
/ 19 декабря 2011

Я сосредоточен на проекте по добавлению поддержки изображений на основе rtf-редактора OmniGroup. Я столкнулся с проблемой, когда использую CTFramesetterCreateWithAttributedString, и он получает

EXC_BAD_ACCESS

вызвано объектом зомби.

Для простоты я получаю NSAttributedString из файла rtfd, в котором есть только фотография. Я добавляю метод для синтаксического анализа тега изображения на iOS на основе образца Omni. И за частью, создающей NSAttributedString, следует руководство от 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, и он успешно создается, и проблем с памятью не возникает. Однако, когда я вызываю CTFramesetterCreateWithAttributedString в моем классе представления, он получает проблему EXC_BAD_ACESS. Я отправляю CTFramesetterCreateWithAttributedString на мой взгляд в viewDidLoad:


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 - это значение OUIEditableFrame, предоставленное OmniFramework. После этого в layoutSubview: из OUIEditableFrame, CTFramesetterCreateWithAttributedString не удалось. Профилируя с помощью инструмента, он указывает на наличие объекта зомби в:


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

Это показывает, что

Сообщение Objective C было отправлено освобожденному объекту (зомби) по адресу

Я не так хорошо знаком с базовым фундаментом, как UIKit или другие. Итак, я хотел бы знать, что не так с методом создания атрибутной строки для изображения с CTRunDelegateRef в моем коде?

Спасибо!

1 Ответ

0 голосов
/ 19 декабря 2011

CTRunDelegateCreate создать делегата с произвольным указателем контекста (void *).Это означает, что словарь imgAttr не сохраняется делегатом.

Необходимо сохранить контекстный словарь при создании делегата и освободить его в обратном вызове dealloc.

...