我在EXC_BAD_ACCESS
内有[UILabel drawRect]
,有时在[UILabel setText]
内。该问题发生在硬件设备和模拟器中。
我没有覆盖drawRect:
方法,也没有对UILabel
类做任何其他特殊操作。标签是通过故事板创建的。
我用NSZombiesEnabled
检查了这个,然后在调试器暂停执行之前不久收到其中一条消息:
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
UILabel
的文字被更改了很多次(可能每秒50次)。
以下是完整的堆栈跟踪,其中调试器在打印上述CFString
错误消息后停止:
#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 ()
为什么会发生此错误?该怎么办?
狂野猜测:我是否必须以线程安全的方式以某种方式访问UILabel
?
更新
文本更改的代码是:
- (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;
}
答案 0 :(得分:3)
错误表示您的标签已被解除分配,并且您正在尝试向死对象(僵尸)发送消息。
可能会发生 - 我猜 - 如果您尝试从后台线程设置标签文本,但可能不会。
您更有可能过度释放标签(手动引用计数)或者没有强烈引用它(ARC),因此它正在被释放。请发布有关标签对象生命周期的代码。他们是如何被创造出来的?您是否将标签添加为当前视图控制器内容视图的子视图?你是否对标签保持强烈的引用?
如果您正在使用手动引用计数,那么您如何处理标签的生命周期?