2

有人可以帮我转换下面的代码以支持 ARC 吗?

UIFont *boldFont = [UIFont fontWithName:@"DINPro-Medium" size:14];
CTFontRef ctBoldFont = CTFontCreateWithName((__bridge CFStringRef)boldFont.fontName, boldFont.pointSize, NULL);
CGColorRef cgColor = UIColorFromRGB(0x2b776d).CGColor;

NSNumber* underline = [NSNumber numberWithInt:kCTUnderlineStyleSingle];
NSDictionary *ULSubattributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                     CFBridgingRelease(ctBoldFont), (id)(id)kCTFontAttributeName,
                                     cgColor, (id)kCTForegroundColorAttributeName,underline, (NSString*)kCTUnderlineStyleAttributeName, nil];

我在最后一行说崩溃了,

*** -[Not A Type retain]: message sent to deallocated instance 0x20ad4910
*** -[Not A Type class]: message sent to deallocated instance 0x20ad4910

我希望这是一个重复的问题。但我被困住了。谢谢。

4

2 回答 2

3

这是我的一些实际工作代码,它们的功能与您的非常相似:

 CTFontRef font2 =
     CTFontCreateCopyWithSymbolicTraits (
         basefont, f, nil, kCTFontBoldTrait, kCTFontBoldTrait);
 NSDictionary* d2 =
     @{(NSString*)kCTFontAttributeName: CFBridgingRelease(font2)};
 [mas addAttributes:d2 range:encRange];

请注意,我释放font2CFBridgingRelease意思是“ARC,这个对象已经被保留了,到时候释放它。” 而ARC确实如此。没有泄漏,没有僵尸,没有崩溃,没有问题。

(另一方面,basefont较早创建CTFontCreateWithName并从未移交给 ARC 进行控制的 ,必须使用 显式释放CFRelease。)

这是我书中更多的核心文本代码,贯穿始终显示 ARC 内存管理:

http://www.aeth.com/iOSBook/ch23.html#_core_text

这是我书中关于使用 ARC 进行 CFType 内存管理的部分:

http://www.aeth.com/iOSBook/ch12.html#_memory_management_of_cftyperefs

于 2013-04-12T15:47:38.643 回答
2
/* OK */UIFont *boldFont = [UIFont fontWithName:@"DINPro-Medium" size:14];
assert(boldFont); // just be sure
/* OK */CTFontRef ctBoldFont = CTFontCreateWithName((__bridge CFStringRef)boldFont.fontName, boldFont.pointSize, NULL);
assert(boldFont); // just be sure

/* 1) CGColorRef cgColor = UIColorFromRGB(0x2b776d).CGColor; */
CGColorRef cgColor = CGColorCreateCopy( UIColorFromRGB(0x2b776d).CGColor );
assert(cgColor); // just to be sure

/* OK */NSNumber* underline = [NSNumber numberWithInt:kCTUnderlineStyleSingle];

NSDictionary *ULSubattributes = @{ 
/* you don't own the kCT strings */(__bridge NSString *)kCTFontAttributeName : CFBridgingRelease(ctBoldFont),
/* ... */   (__bridge NSString *)kCTForegroundColorAttributeName : CFBridgingRelease(cgColor),
/* ... */   (__bridge NSString *)kCTUnderlineStyleAttributeName : underline };

1) iOS pre-iOS6 中存在一个错误,当您仍在使用 CGColorRef 时,ARC 将释放支持 CGColorRef 的 UIColor。我知道这一点,因为我创建了一个 rdar,然后在 iOS 6 中报告为已修复。

PS:这里是 Mike Ash 的一篇不错的博客

编辑:此代码在我的 iOS 演示应用程序中运行良好(部署设置为 5.1 和 6) - 请参阅日志消息。我把 dict 变成了 ivar。

{

    UIFont *boldFont = [UIFont fontWithName:@"Helvetica" size:14];
    assert(boldFont); // just be sure
    CTFontRef ctBoldFont = CTFontCreateWithName((__bridge CFStringRef)boldFont.fontName, boldFont.pointSize, NULL);
    assert(boldFont); // just be sure

    CGColorRef cgColor = CGColorCreateCopy( [UIColor colorWithRed:0.8f green:0.8f blue:0.8f alpha:0.8f].CGColor );
    assert(cgColor);

    NSNumber* underline = [NSNumber numberWithInt:kCTUnderlineStyleSingle];
    assert(underline);

    ULSubattributes = @{ 
        (__bridge NSString *)kCTFontAttributeName : CFBridgingRelease(ctBoldFont),
        (__bridge NSString *)kCTForegroundColorAttributeName : CFBridgingRelease(cgColor),
        (__bridge NSString *)kCTUnderlineStyleAttributeName : underline };

    NSLog(@"ULSubattributes: %@", ULSubattributes);
}

2013-04-12 11:48:20.294 WebViewScrollTester[44147:c07] ULSubattributes: { CTForegroundColor = " [ (kCGColorSpaceDeviceRGB)] ( 0.8 0.8 0.8 0.8 )"; NSFont = "CTFont \nCTFontDescriptor {type = mutable dict, count = 1,\nentries =>\n\t1 : {contents = \"NSFontNameAttribute\"} = {contents = \"Helvetica\"}\n}\n> "; NSUnderline = 1; }

EDIT2:我什至添加了一个 dispatch_after 以显示 ARC 没有发布任何内容:

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^
        {
            NSLog(@"ULSubattributes: %@", ULSubattributes);
        } );
于 2013-04-12T14:44:46.323 回答