1

我有使用sizeWithFont方法的应用程序。它在 iOS 7 上大约 5% 的应用程序启动时崩溃。该方法在 SDK 7 上已弃用,因此我将其替换为以下类别:

#import "NSString+mySizeWithFont.h"
#import "Constants.h"

@implementation NSString (mySizeWithFont)

- (CGSize)mySizeWithFont:(UIFont *)font {
    if (is_iOS7) {
        CGSize size = CGSizeMake(MAXFLOAT, MAXFLOAT);
        return [self mySizeWithFont:font constrainedToSize:size];
    } else {
        return [self sizeWithFont:font];
    }
}

- (CGSize)mySizeWithFont:(UIFont*)font constrainedToSize:(CGSize)size {
    if (is_iOS7) {
        NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil];
        CGRect frame = [self boundingRectWithSize:size options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) attributes:attributesDictionary context:nil];
        return frame.size;
    } else {
        return [self sizeWithFont:font constrainedToSize:size];
    }
}

@end

但是现在我在同样的 5% 的发布中又发生了一次崩溃。有两种类型的崩溃报告:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0005006f
Triggered by Thread:  0

Thread 0 Crashed:
0   libobjc.A.dylib                 0x3902cb76 objc_msgSend + 22
1   CoreFoundation                  0x2ec74c56 +[__NSDictionaryI __new:::::] + 358
2   CoreFoundation                  0x2ec749c6 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 238
3   CoreFoundation                  0x2ec794d4 +[NSDictionary dictionaryWithObjectsAndKeys:] + 372
4   *** MYAPP ***                   0x000cd99e -[NSString(mySizeWithFont) mySizeWithFont:constrainedToSize:] (NSString+mySizeWithFont.m:25)
5   *** MYAPP ***                   0x000cd7e6 -[NSString(mySizeWithFont) mySizeWithFont:] (NSString+mySizeWithFont.m:17)
6   *** MYAPP ***                   0x000d36ae -[LiteVersionHomepageLink drawRect:] (LiteVersionHomepageLink.m:43)

和这个:

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Triggered by Thread:  0

Last Exception Backtrace:
0   CoreFoundation                  0x2ed36e86 __exceptionPreprocess + 126
1   libobjc.A.dylib                 0x390316c2 objc_exception_throw + 34
2   CoreFoundation                  0x2ed3a7b2 -[NSObject(NSObject) doesNotRecognizeSelector:] + 198
3   CoreFoundation                  0x2ed390b2 ___forwarding___ + 702
4   CoreFoundation                  0x2ec87e94 __forwarding_prep_0___ + 20
5   UIFoundation                    0x3660790e __NSStringDrawingEngine + 2950
6   UIFoundation                    0x36606d5a -[NSString(NSExtendedStringDrawing) boundingRectWithSize:options:attributes:context:] + 130
7   *** MYAPP ***                   0x000e89d4 -[NSString(mySizeWithFont) mySizeWithFont:constrainedToSize:] (NSString+mySizeWithFont.m:26)
8   *** MYAPP ***                   0x000e87e6 -[NSString(mySizeWithFont) mySizeWithFont:] (NSString+mySizeWithFont.m:17)
9   *** MYAPP ***                   0x000ee6ae -[LiteVersionHomepageLink drawRect:] (LiteVersionHomepageLink.m:43)

LiteVersionHomepageLink 继承自 UIView:

@interface LiteVersionHomepageLink : UIView {
    NSString *text;
    UIFont *textFont;
}

mySizeWithFont从以下方法调用:

- (void)drawRect:(CGRect)rect {
    [[UIImage imageNamed:@"cal_top_back@2x"] drawInRect:rect];
    if (text && textFont) {
        [[UIColor whiteColor] set];
        float height = [text mySizeWithFont:textFont].height / 2;
        [text drawInRect:CGRectMake(0, rect.size.height / 2  - height, rect.size.width, rect.size.height / 2 + height) withFont:textFont lineBreakMode:NSLineBreakByCharWrapping alignment:NSTextAlignmentCenter];
    }
}

怎么了?如何修复崩溃?非常感谢您的帮助!

4

2 回答 2

2

在我看来,您正在使用无效字体调用例程 mySizeWithFont。要么已释放,要么从未分配过。我会在您的字体分配附近和面包屑之前放入 NSLog 面包屑,以确保首先分配您的字体。如果是这样,可能是 ARC 在你使用它之前会扔掉你的字体 - 可能需要 @property(strong) 或类似的东西。

于 2013-10-15T19:01:18.990 回答
2

我的两分钱:在我的应用程序中,我有一个UIFont对象的过度发布错误。我会调用[UIFont systemFontOfSize:]并将结果存储在文件静态变量中而不保留。

直到 iOS 7,我都会侥幸逃脱,然后[sizeWithFont]开始崩溃。看起来 iOS<7 会从池或缓存中返回字体实例,因此单个不匹配release不会释放它们。在 iOS 7 中 - 不再。

于 2013-10-27T14:21:53.987 回答