崩溃在actionForLayer:forKey:

时间:2011-06-17 10:07:42

标签: iphone ios uiview calayer exc-bad-access

在更改某些UILabel的帧时,我有一个神秘的EXC_BAD_ACCESS。崩溃是随机的,通常我必须重复几分钟的条件。

启用NSZombies以及其他内存调试标志(NSDebugEnabled,MallocStackLogging)没有帮助,崩溃仍然保持不透明:只是一个BAD_ACCESS,控制台中没有消息。目标似乎正确且有效,因此它看起来不像是一个解除分配的内存问题。

为了获得更多信息,我将UILabel子类化并重写了崩溃函数:

@implementation TestUILabel
- (id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event {
    return [super actionForLayer:layer forKey:event];
}
@end

它在super的方法中崩溃,但在检查时一切似乎都正确(打印retainCount为'self'和'layer'分别给出3和2):

  

(gdb)po self

     

&LT; TestUILabel:0x6ac2800;   baseClass = UILabel; frame =(173 174;   0 0); text ='54m²'; opaque = NO;   autoresize = LM + TM;   autoresizesSubviews = NO;   userInteractionEnabled = NO;   动画= {   位置= LT; CABasicAnimation:   0xe07ba60取代; }; layer =&lt; CALayer的:   0xbf1b950&GT;&GT;

     

(gdb)po event

     

边界

     

(gdb)po layer

     

&LT; CALayer的:0xbf1b950;   position = CGPoint(173 174); bounds =   CGRect(0 0; 0 0);代表=   &LT; TestUILabel:0x6ac2800; baseClass =   的UILabel; frame =(173 174; 0 0);文本   ='54m²'; opaque = NO; autoresize = LM + TM; autoresizesSubviews = NO;   userInteractionEnabled = NO;   动画= {   位置= LT; CABasicAnimation:   0xe07ba60取代; }; layer =&lt; CALayer的:   0xbf1b950&GT;取代; contents =&lt; CGImage   0xe04ed60取代;不透明度= 1;动画=   [位置= LT; CABasicAnimation:   0xe07ba60&GT;]&GT;

是否有人遇到类似的问题?或者有什么想法可以来自哪里?

提前致谢!

编辑: 这是完整的崩溃回溯:

  

线程1,队列:
  com.apple.main线程
  #0 0x00459b2c in - [UIView(CALayerDelegate)actionForLayer:forKey:]()
  #1 0x00eaaac7 in - [CALayer actionForKey:]()
  #2 0x00ea80fe in actionForKey(CALayer *,   CA :: Transaction *,NSString *)()
  #3 0x00ea8066在beginChange中(CALayer *,CA :: Transaction *,unsigned int,   objc_object *&amp;)()
  CALAYerSetPosition中的#4 0x00eaba3a(CALayer *,   CA :: Vec2 const&amp;,bool)()
  #5 0x00eab8b5 in - [CALayer setPosition:]()
  #6 0x00eab7cc in - [CALayer setFrame:]()
  #7 0x0045739d in - [UIView(Geometry)setFrame:]()
  #8 0x00542a68 in - [UILabel setFrame:]()
  #9 0x0000a97f in - [MosaicElementView setupWithAdvert:] at   /Users/eino/Prog/AJ/Classes/Search/SubViews/MosaicElementView.m:30
  #10 0x00079cb9 in - [SearchResultsViewController setupElement:withCell:indexPath:actualIndex:]   ()
  #11 0x000797a2 in - [SearchResultsViewController tableView:cellForRowAtIndexPath:]()
  #12 0x004957fa in - [UITableView(UITableViewInternal)_createPreparedCellForGlobalRow:withIndexPath:]   ()
  #13 0x0048b77f in - [UITableView(UITableViewInternal)_createPreparedCellForGlobalRow:]()
  #14 0x004a0450 in - [UITableView(_UITableViewPrivate)_updateVisibleCellsNow:]()
  #15 0x00498538 in - [UITableView layoutSubviews]()
  #16 0x00eb0451 in - [CALayer layoutSublayers]()
  CALayerLayoutIfNeeded()中的#17 0x00eb017c   CA :: Context :: commit_transaction(CA :: Transaction *)中的#18 0x00ea937c   ()
  CA :: Transaction :: commit()()中的#19 0x00ea90d0   CA :: Transaction :: observer_callback中的#20 0x00ed97d5(__ CFRunLoopObserver *,   unsigned long,void *)()
  __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__中的#21 0x017e9fbb   ()
  在__CFRunLoopDoObservers()中#22 0x0177f0e7   __CFRunLoopRun()中的#23 0x01747bd7   #24 0x01747240在CFRunLoopRunSpecific()中   #25 0x01747161在CFRunLoopRunInMode()中   #26 0x01e7d268在GSEventRunModal()中   GSEventRun()中的#27 0x01e7d32d   #28 0x0043042e在UIApplicationMain()中   #29 0x000021fe主要位于/Users/eino/Prog/AJ/main.m:11

第9帧的删除线基本上只是帧更改:

labelPrice.frame = rect;

使用rect是正确的CGRect(106,143,86,22)。

2 个答案:

答案 0 :(得分:10)

你可能已经检查了这个,但它值得拍摄......

您确定自己没有做任何影响后台线程中任何UI元素的事情吗?也许您正在进行与此搜索相关的一些计算,并且它会更改某个视图的属性。

在我忘记了performSelectorOnMainThread:withObject:waitUntilDone:调用然后在后台更改了UI的情况下,我看到了他的那种情况。

答案 1 :(得分:1)

此崩溃具有非主线程,似乎使用UIKit类或函数。一般来说,从主线程中使用UIKit是安全的。从后台线程调用UIKit会导致不可预测的行为(如崩溃!)。请仔细检查所有代码(不在主线程上)是否已被Apple明确标记为可在后台使用。

外部资源:

UIKit Framework Reference