我的iPad应用程序有时会在启动时挂起。看起来主线程正在与另一个线程陷入僵局,但不确定原因。关于是什么导致这个以及如何调试这个的任何想法?
仅供参考我的应用程序作为splitview控制器启动,左侧是列表视图,右侧是webview。如果我以纵向模式启动并隐藏列表视图,则不会出现问题。此外,如果我不在主线程上禁用我的单元格的渲染,应用程序不会挂起,但单元格显示为黑色矩形。
谢谢!
这是我的主线程。这个堆栈上的所有代码都是Apple框架......
#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 :(得分:3)
我看起来你已经创建了另一个帖子,例如通过[object performSelectorInBackground:@selector(foo) withObject:bar]
。在该线程中,您调用GUI方法。您应该使用[object performSelectorOnMainThread:@selector(alpha) withObject:beta waitUntilDone:YES]
调用GUI方法(可能创建另一个只包含GUI方法的方法,并以这种方式调用它,而不是执行20个performSelectorOnMainThreads)。
所有GUI方法都应该在主线程上运行。
答案 1 :(得分:1)
您是否在代码中的某处使用CATransitions?
Core Animation支持两种类型的事务:隐式事务和显式事务。当没有活动事务的线程修改层树时,会自动创建隐式事务,并在线程的run-loop下一次迭代时自动提交。当应用程序在修改层树之前向CATransaction类发送begin消息并在之后发送提交消息时,会发生显式事务。
似乎隐式事务可以在从那里调用drawRect的后台线程中触发。 如果主线程中同时有一些绘图 - 你遇到了麻烦。
在这种情况下,[CATransaction begin] / [CATransaction commit]可以提供帮助。