I get EXC_BAD_ACCESS
inside [UILabel drawRect]
and sometimes inside [UILabel setText]
. The problem occurs on the hardware device and in Simulator.
I haven't overwritten the drawRect:
method, nor did I do anything else special with the UILabel
class. The label is created through a storyboard.
I've examined this with NSZombiesEnabled
and then I get one of these messages shortly before the debugger suspends the execution:
2014-04-22 20:35:42.032 AppName[5621:a0b] *** -[CFString length]: message sent to deallocated instance 0x1191c730
2014-04-22 20:33:43.447 AppName[5607:a0b] *** -[NSConcreteMutableAttributedString length]: message sent to deallocated instance 0x12a58760
The UILabel
's text is changed a lot of times (maybe 50 times per second).
Here is the complete stack trace where the debugger stopped after the above CFString
error message was printed:
#0 0x03619811 in ___forwarding___ ()
#1 0x036194ee in _CF_forwarding_prep_0 ()
#2 0x00f38183 in -[NSConcreteMutableAttributedString length] ()
#3 0x00efe25f in -[NSAttributedString enumerateAttributesInRange:options:usingBlock:] ()
#4 0x014c1dea in -[NSAttributedString(UILabelAdditions) _ui_synthesizeAttributedSubstringFromRange:usingDefaultAttributes:] ()
#5 0x014c2d89 in -[UILabel _synthesizedAttributedText] ()
#6 0x014c84da in -[UILabel _drawTextInRect:baselineCalculationOnly:] ()
#7 0x014c7b94 in -[UILabel drawTextInRect:] ()
#8 0x014c9b0e in -[UILabel drawRect:] ()
#9 0x01381d56 in -[UIView(CALayerDelegate) drawLayer:inContext:] ()
#10 0x00c0fdc9 in -[CALayer drawInContext:] ()
#11 0x00c0fcfa in backing_callback(CGContext*, void*) ()
#12 0x00b00cf4 in CABackingStoreUpdate_ ()
#13 0x00c0fc92 in ___ZN2CA5Layer8display_Ev_block_invoke ()
#14 0x00c43b23 in x_blame_allocations ()
#15 0x00c0fafd in CA::Layer::display_() ()
#16 0x00c0fd49 in -[CALayer _display] ()
#17 0x00c0f506 in CA::Layer::display() ()
#18 0x00c0fd23 in -[CALayer display] ()
#19 0x00c03ed3 in CA::Layer::display_if_needed(CA::Transaction*) ()
#20 0x00c03f4c in CA::Layer::layout_and_display_if_needed(CA::Transaction*) ()
#21 0x00b6bae6 in CA::Context::commit_transaction(CA::Transaction*) ()
#22 0x00b6ce71 in CA::Transaction::commit() ()
#23 0x00c38aea in CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) ()
#24 0x00c38f6b in CA::Display::TimerDisplayLink::callback(__CFRunLoopTimer*, void*) ()
#25 0x035e7bd6 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ ()
#26 0x035e75bd in __CFRunLoopDoTimer ()
#27 0x035cf628 in __CFRunLoopRun ()
#28 0x035ceac3 in CFRunLoopRunSpecific ()
#29 0x035ce8db in CFRunLoopRunInMode ()
#30 0x035549e2 in GSEventRunModal ()
#31 0x03554809 in GSEventRun ()
#32 0x01317d3b in UIApplicationMain ()
#33 0x00002f0d in main at (I've cut the path to the project's home.)/main.m:18
#34 0x02d98725 in start ()
Why does this error take place? What to do about it?
Wild guess: Do I have to access UILabel
somehow in a thread-safe manner?
UPDATE:
The code where the text is changes is this:
- (void)updateTimeLabels:(NSTimeInterval)timeInterval {
NSDate *timeIntervalDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSString *timeIntervalStr = [_TIME_FORMATTER stringFromDate:timeIntervalDate];
NSString *timeSecondfractionStr = [_SECONDFRACTION_FORMATTER stringFromDate:timeIntervalDate];
if (![NSThread isMainThread]) { // i've added these 3 lines for checking
NSLog(@"%s: not on the main thread", __FUNCTION__); // I have not observed this being printed ever
}
self.timeCodeLabel.text = timeIntervalStr; // this is the line where sometimes the error takes place
self.timeCodeSecondfractionLabel.text = timeSecondfractionStr;
}