1

我的iPad应用程序有时会挂起。它看起来像主线程与另一个线程僵局,但不知道为什么。任何想法是什么导致这个以及如何调试?启动时iOS iPad GUI死锁。在启动屏幕上挂起

仅供参考我的应用程序最初是一个分割视图控制器,左侧是一个listview,右侧是一个webview。如果我以隐藏列表视图的纵向模式启动,则不会发生问题。另外,如果我在不在主线程上时禁用了我的单元格渲染,应用程序不会挂起,但单元格显示为黑色矩形。

谢谢!

这是我的主线程。在这个堆栈上的所有代码是苹果框架...

#0 0x971c0142 in semaphore_wait_signal_trap() 
#1 0x971c5c06 in pthread_mutex_lock() 
#2 0x02685903 in CGFontCacheLock() 
#3 0x02685869 in CGGlyphLockLockGlyphBitmaps() 
#4 0x0a90bb5b in ripc_RenderGlyphs() 
#5 0x0a9199f8 in ripc_DrawGlyphs() 
#6 0x0268464c in draw_glyphs() 
#7 0x02683e97 in CGContextShowGlyphsWithAdvances() 
#8 0x035aafba in WebCore::Font::drawGlyphs() 
#9 0x035aaaf5 in WebCore::Font::drawGlyphBuffer() 
#10 0x035aa81a in WebCore::Font::drawSimpleText() 
#11 0x035aa4c0 in drawAtPoint() 
#12 0x035a9d5c in -[NSString(WebStringDrawing) _web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:]() 
#13 0x0043f632 in -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:includeEmoji:]() 
#14 0x0043f325 in -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:]() 
#15 0x0055ba70 in -[UILabel _drawTextInRect:baselineCalculationOnly:]() 
#16 0x00559178 in -[UILabel drawTextInRect:]() 
#17 0x0045418f in -[UIView(CALayerDelegate) drawLayer:inContext:]() 
#18 0x02a708d2 in -[CALayer drawInContext:]() 
#19 0x02a704b0 in backing_callback() 
#20 0x02a6fd52 in CABackingStoreUpdate() 
#21 0x02a6f01d in -[CALayer _display]() 
#22 0x02a6eac7 in CALayerDisplayIfNeeded() 
#23 0x02a609e1 in CA::Context::commit_transaction() 
#24 0x02a60732 in CA::Transaction::commit() 
#25 0x00427556 in -[UIApplication _reportAppLaunchFinished]() 
#26 0x0042dd3e in -[UIApplication handleEvent:withNewEvent:]() 
#27 0x004294f7 in -[UIApplication sendEvent:]() 
#28 0x004311d8 in _UIApplicationHandleEvent() 
#29 0x033f817c in PurpleEventCallback() 
#30 0x02bec89c in CFRunLoopRunSpecific() 
#31 0x02beb8a8 in CFRunLoopRunInMode() 
#32 0x00427221 in -[UIApplication _run]() 
#33 0x0042f372 in UIApplicationMain() 

而另一个线程呈现我的列表视图中的单元格。 MyFancyPantsCell & ABTableViewCellView是我的课程。

#0 0x971c0142 in semaphore_wait_signal_trap() 
#1 0x971c5c06 in pthread_mutex_lock() 
#2 0x02685903 in CGFontCacheLock() 
#3 0x02685869 in CGGlyphLockLockGlyphBitmaps() 
#4 0x0a90bb5b in ripc_RenderGlyphs() 
#5 0x0a9199f8 in ripc_DrawGlyphs() 
#6 0x0268464c in draw_glyphs() 
#7 0x02683e97 in CGContextShowGlyphsWithAdvances() 
#8 0x035aafba in WebCore::Font::drawGlyphs() 
#9 0x035aaaf5 in WebCore::Font::drawGlyphBuffer() 
#10 0x035aa81a in WebCore::Font::drawSimpleText() 
#11 0x035aa4c0 in drawAtPoint() 
#12 0x035a9d5c in -[NSString(WebStringDrawing) _web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:]() 
#13 0x0043f632 in -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:includeEmoji:]() 
#14 0x0043f381 in -[NSString(UIStringDrawing) drawAtPoint:withFont:]() 
#15 0x000635ec in -[SymbolCellPainter drawContentView:selected:editing:frame:] 
#16 0x000452d0 in -[MyFancyPantsCell drawContentView:] 
#17 0x00044624 in -[ABTableViewCellView drawRect:] 
#18 0x0045418f in -[UIView(CALayerDelegate) drawLayer:inContext:]() 
#19 0x02a708d2 in -[CALayer drawInContext:]() 
#20 0x02a704b0 in backing_callback() 
#21 0x02a6fd52 in CABackingStoreUpdate() 
#22 0x02a6f01d in -[CALayer _display]() 
#23 0x02a6eac7 in CALayerDisplayIfNeeded() 
#24 0x02a609e1 in CA::Context::commit_transaction() 
#25 0x02a60732 in CA::Transaction::commit() 
#26 0x02a9e04f in CA::Transaction::release_thread() 
#27 0x971f61e3 in _pthread_tsd_cleanup() 
#28 0x971f5df6 in _pthread_exit() 
#29 0x00183bf2 in +[NSThread exit]() 
#30 0x00183b5b in __NSThread__main__() 
#31 0x971ed81d in _pthread_start() 
#32 0x971ed6a2 in thread_start() 
+0

这是一个可疑的死锁,因为它看起来像他们都在同一个对象上等待(除非有多个字体缓存,这不应该是)。但是UIGraphics */NSString绘图/ UIImage绘图在4.0之前记录为无线程安全。 – 2010-08-21 07:52:17

回答

3

我看起来像你已经创建了另一个线程,例如,通过[object performSelectorInBackground:@selector(foo) withObject:bar]。在那个线程中你可以调用GUI方法。您应该使用[object performSelectorOnMainThread:@selector(alpha) withObject:beta waitUntilDone:YES]调用GUI方法(也许创建另一种方法,只包含GUI方法,并以此方式调用该方法,而不是执行performSelectorOnMainThreads)。

所有GUI方法都应该在主线程上运行。

+0

谢谢......现在我真正想知道的是如何检测何时从GUI线程中做出不安全的东西。调试提示。因为“另一个”线程堆栈中没有多少线索。它似乎是挂钩到线程关闭的一些核心动画代码。但是你看不到代码要求视图在线程关闭时显示自己。 – Cal 2010-08-19 04:06:33

+0

规则很简单,我猜:只在主线程中调用UI *类型的对象的方法。但是对于调试:一个棘手的问题恐怕我不知道如何在这里找到罪魁祸首。 – DarkDust 2010-08-27 06:49:30

1

你是否在你的代码中使用了CATransitions?

核心动画支持两种类型的事务:隐式事务和显式事务。隐式事务是在没有活动事务的线程修改层树时自动创建的,并且在线程的下一次迭代运行循环时自动提交。显式事务发生在应用程序在修改层树之前向CATransaction类发送开始消息并在之后发送提交消息时发生。

似乎隐式事务可以在后台线程调用drawRect从那里触发。 如果在主线程中同时进行了一些绘图 - 您遇到了麻烦。

在这种情况下,[CATransaction begin]/[CATransaction commit]可以提供帮助。