Question

I have the application that uses sizeWithFont method. It crashes on about 5% of launches of the application on iOS 7. The method is deprecated on SDK 7, so I replaced it with the following category:

#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

But now I have another crashes on the same 5% of launches. There are crash reports of 2 types:

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)

And this one:

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 is inherited from UIView:

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

And mySizeWithFont is called from the following method:

- (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];
    }
}

What's wrong? How to fix crashes? Thanks a lot for any help!

Was it helpful?

Solution

It looks to me like you're calling your routine mySizeWithFont with an invalid font. Either one that has been released, or one that was never allocated. I'd put in NSLog breadcrumbs near your font allocation and just before the breadcrumbs to make sure your font is allocated first. If it is, it may be that ARC is tossing your font before you go to use it - may need @property(strong) or something like that.

OTHER TIPS

My two cents: I had, in my app, an overrelease bug with a UIFont object. I'd invoke [UIFont systemFontOfSize:] and store the result in a file-static variable without retaining.

Up until iOS 7, I'd get away with it, then crashes in [sizeWithFont] started coming. Looks like iOS<7 would return font instances from a pool or a cache, so that a single unmatched release won't deallocate them. In iOS 7 - not anymore.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top