神秘崩溃(NSAttributedString,iOS 7)
在我的应用程序中,我有一个自制的UICollectionView版本(我在UICollectionView存在之前编写它,并且它比我的用例更像UICollectionView)。 它由多个滚动视图中的图块组成。
为了帮助滚动性能,并且由于每个tile都由十几个PNG组成,所以每个tile都使用NSOperations和NSOperationQueue预渲染为NSCache。 如果没有这种优化,滚动性能会很糟糕。
以及几个PNG,每个瓷砖都有(或可能有)几段文字。
每个NSOperation,为了避免在后台线程上进行任何类型的渲染(这当然是UIKit禁止),使用CoreGraphics和NSAttributedStrings来渲染图像。
这让我陷入了崩溃。 崩溃(下图)似乎与NSAttributedString呈现有关。 由于这个充满tile渲染操作的NSOperationQueue是我的应用程序中唯一使用NSAttributedStrings的地方,并且被调用了很多,所以我必须假定它是罪魁祸首。 我们发现崩溃报告中经常发生崩溃,但经常不足以让我们有希望在内部可靠地进行再现(我们的应用程序拥有相当庞大的用户群)。
令人着迷的是,这次崩溃只发生在iOS 7上。任何人有任何想法? 这是一个崩溃的例子:
Incident Identifier: 3BE1FF37-4288-40A9-954D-1AD909987D05
CrashReporter Key: 000339CB-9B5B-46EE-B256-4D911B190E7D
Hardware Model: iPhone5,2
Process: AppName [733]
Path: /Users/USER/AppName.app/AppName
Identifier: com.companyname.appname
Version: 2.0.1
Code Type: ARM
Parent Process: launchd [1]
Date/Time: 2013-10-03 23:32:20 +0000
OS Version: iPhone OS 7.0.2 (11A501)
Report Version: 104
Exception Type: SIGBUS
Exception Codes: BUS_ADRALN at 0x100078c
Crashed Thread: 0
Thread 0 Crashed:
0 ??? 0x0100078c 0x0 + 0
1 UIFoundation 0x36fbf027 -[NSLayoutManager _drawLineForGlyphRange:type:baselineOffset:lineFragmentRect:lineFragmentGlyphRange:containerOrigin:isStrikethrough:] + 3358
2 UIFoundation 0x36ffdd1f -[NSLayoutManager drawUnderlineForGlyphRange:underlineType:baselineOffset:lineFragmentRect:lineFragmentGlyphRange:containerOrigin:] + 86
3 UIFoundation 0x36fc024d -[NSLayoutManager _lineGlyphRange:type:lineFragmentRect:lineFragmentGlyphRange:containerOrigin:isStrikethrough:] + 1184
4 UIFoundation 0x36ffde2f -[NSLayoutManager underlineGlyphRange:underlineType:lineFragmentRect:lineFragmentGlyphRange:containerOrigin:] + 78
5 UIFoundation 0x36fd43bf -[NSLayoutManager _drawGlyphsForGlyphRange:atPoint:] + 5734
6 UIFoundation 0x36ffdbf7 -[NSLayoutManager drawGlyphsForGlyphRange:atPoint:] + 38
7 UIFoundation 0x37013f01 -[NSStringDrawingTextStorage drawTextContainer:withRect:graphicsContext:baselineMode:scrollable:padding:] + 968
8 UIFoundation 0x3700e5bd __NSStringDrawingEngine + 10293
9 UIFoundation 0x3701172d -[NSAttributedString(NSExtendedStringDrawing) drawWithRect:options:context:] + 525
10 UIKit 0x31ed9f5d -[UILabel _drawTextInRect:baselineCalculationOnly:] + 3436
11 UIKit 0x31f419e7 -[UILabel drawTextInRect:] + 558
12 UIKit 0x31f417af -[UILabel drawRect:] + 78
13 UIKit 0x31f41749 -[UIView drawLayer:inContext:] + 372
14 QuartzCore 0x31b78049 -[CALayer drawInContext:] + 100
15 QuartzCore 0x31b61813 CABackingStoreUpdate_ + 1859
16 QuartzCore 0x31c3b735 ___ZN2CA5Layer8display_Ev_block_invoke + 53
17 QuartzCore 0x31b610c3 x_blame_allocations + 83
18 QuartzCore 0x31b60d77 CA::Layer::display_() + 1119
19 QuartzCore 0x31b44969 CA::Layer::display_if_needed(CA::Transaction*) + 209
20 QuartzCore 0x31b44601 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 25
21 QuartzCore 0x31b4400d CA::Context::commit_transaction(CA::Transaction*) + 229
22 QuartzCore 0x31b43e1f CA::Transaction::commit() + 315
23 QuartzCore 0x31b3db4d CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 57
24 CoreFoundation 0x2f706f71 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 21
25 CoreFoundation 0x2f7048ff __CFRunLoopDoObservers + 287
26 CoreFoundation 0x2f704c4b __CFRunLoopRun + 739
27 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
28 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
29 GraphicsServices 0x343a62eb GSEventRunModal + 138
30 UIKit 0x31f261e5 UIApplicationMain + 1136
31 My App 0x0002cc37 main (main.m:18)
32 libdyld.dylib 0x39f2fab7 start + 3
Thread 1:
0 libsystem_kernel.dylib 0x39fd3838 kevent64 + 24
1 libdispatch.dylib 0x39f1c643 _dispatch_mgr_thread + 39
Thread 2:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
5 Foundation 0x3005d827 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 255
6 Foundation 0x300ae669 -[NSRunLoop(NSRunLoop) run] + 81
7 My App 0x0003900f -[EndpointOperation start] (EndpointOperation.m:268)
8 Foundation 0x3010eafd __NSOQSchedule_f + 61
9 libdispatch.dylib 0x39f1f4bf _dispatch_async_redirect_invoke + 111
10 libdispatch.dylib 0x39f207e5 _dispatch_root_queue_drain + 225
11 libdispatch.dylib 0x39f209d1 _dispatch_worker_thread2 + 57
12 libsystem_pthread.dylib 0x3a04adff _pthread_wqthread + 298
13 libsystem_pthread.dylib 0x3a04acc4 start_wqthread + 8
Thread 3:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
5 Foundation 0x300aa651 +[NSURLConnection _resourceLoadLoop:] + 320
6 Foundation 0x3011fdc7 __NSThread__main__ + 1063
7 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
8 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
9 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 4:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
5 Foundation 0x3005d827 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 255
6 My App 0x000a1287 +[XMPPStream xmppThreadMain] (XMPPStream.m:4463)
7 Foundation 0x3011fdc7 __NSThread__main__ + 1063
8 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
9 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
10 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 5:
0 libsystem_kernel.dylib 0x39fe6440 __select + 20
1 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
2 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
3 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 6:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
5 WebCore 0x375d27dd RunWebThread(void*) + 421
6 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
7 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
8 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 7:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
5 libAVFAudio.dylib 0x2e64d5b3 GenericRunLoopThread::Entry(void*) + 131
6 libAVFAudio.dylib 0x2e641bf7 CAPThread::Entry(CAPThread*) + 179
7 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
8 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
9 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 8:
0 libsystem_kernel.dylib 0x39fe5f38 __psynch_cvwait + 24
1 libsystem_pthread.dylib 0x3a04d041 pthread_cond_wait + 40
2 JavaScriptCore 0x3069340d JSC::BlockAllocator::blockFreeingThreadMain() + 209
3 JavaScriptCore 0x30690a73 WTF::wtfThreadEntryPoint(void*) + 15
4 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
5 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
6 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 9:
0 libsystem_kernel.dylib 0x39fe5f38 __psynch_cvwait + 24
1 libsystem_pthread.dylib 0x3a04d041 pthread_cond_wait + 40
2 JavaScriptCore 0x30831af7 JSC::GCThread::waitForNextPhase() + 79
3 JavaScriptCore 0x30831b51 JSC::GCThread::gcThreadMain() + 53
4 JavaScriptCore 0x30690a73 WTF::wtfThreadEntryPoint(void*) + 15
5 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
6 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
7 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 10:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f66f323 CFRunLoopRunInMode + 106
5 Foundation 0x3005d827 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 255
6 Foundation 0x300ae669 -[NSRunLoop(NSRunLoop) run] + 81
7 My App 0x000b1635 +[GCDAsyncSocket cfstreamThread] (GCDAsyncSocket.m:6714)
8 Foundation 0x3011fdc7 __NSThread__main__ + 1063
9 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
10 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
11 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 11:
0 libsystem_kernel.dylib 0x39fd3a84 mach_msg_trap + 20
1 CoreFoundation 0x2f706561 __CFRunLoopServiceMachPort + 157
2 CoreFoundation 0x2f704c81 __CFRunLoopRun + 793
3 CoreFoundation 0x2f66f541 CFRunLoopRunSpecific + 524
4 CoreFoundation 0x2f6b31ab CFRunLoopRun + 98
5 CoreMotion 0x2fd27399 CLSF_thorntonUpdate_6x6 + 57225
6 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
7 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
8 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 12:
0 libsystem_kernel.dylib 0x39fd3ad4 semaphore_wait_trap + 8
1 MediaToolbox 0x30b60d0f fpa_AsyncMovieControlThread + 1755
2 CoreMedia 0x2fc9b23f figThreadMain + 195
3 libsystem_pthread.dylib 0x3a04cc5d _pthread_body + 141
4 libsystem_pthread.dylib 0x3a04cbcf _pthread_start + 102
5 libsystem_pthread.dylib 0x3a04acd0 thread_start + 8
Thread 13:
0 libsystem_kernel.dylib 0x39fe6c7c __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x3a04acc4 start_wqthread + 8
Thread 14:
0 libsystem_kernel.dylib 0x39fe6c7c __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x3a04acc4 start_wqthread + 8
Thread 15:
0 libsystem_kernel.dylib 0x39fe6c7c __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x3a04acc4 start_wqthread + 8
Thread 16:
0 libsystem_kernel.dylib 0x39fe6c7c __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x3a04acc4 start_wqthread + 8
Thread 0 crashed with ARM Thread State:
pc: 0x0100078c r7: 0x27ddb5e8 sp: 0x27ddb5b8 r0: 0x16d20b30
r1: 0x27ddb5b8 r2: 0x0100078c r3: 0x00000000 r4: 0x169a6d78
r5: 0x16b33250 r6: 0x2fe140a5 r8: 0x27ddb5b8 r9: 0x164ea8b8
r10: 0x157ea030 r11: 0x00000004 ip: 0x3a265964 lr: 0x2fe1402d
cpsr: 0x40000010
代码如下:
NSMutableDictionary *attributes = [@{NSFontAttributeName: [[self class] unreadChatLabelFont]
, NSForegroundColorAttributeName: [UIColor whiteColor]} mutableCopy];
if ([self unreadChatLabelHasDropShadow]) {
NSShadow *shadow = [[NSShadow alloc] init];
shadow.shadowOffset = CGSizeMake(0, -1);
shadow.shadowColor = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: .5];
attributes[NSShadowAttributeName] = shadow;
}
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString: unreadChats
attributes: attributes];
[attributedString drawAtPoint: labelPosition];
在同一个班级的另一个地方:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShadowWithColor(context, CGSizeMake(0,1), 1.5, [UIColor blackColor].CGColor);
NSDictionary *attributes = @{NSFontAttributeName: [[self class] displayNameFont], NSForegroundColorAttributeName: [UIColor whiteColor]};
NSAttributedString *displayName = [[NSAttributedString alloc] initWithString: dictionary[kDisplayNameKey]
attributes: attributes];
[displayName drawAtPoint: [[self class] displayNamePosition]];
// Remove shadow from draw settings
CGContextSetShadowWithColor(context, CGSizeMake(0,1), 1.5, NULL);
确保您没有添加标签,更改标签中的文本或在主线程以外的线程上绘制文本。 虽然文件确实说明了以下内容:
只要应用程序保证单线程访问,NSTextStorage,NSLayoutManager和NSTextContainer就可以从子线程访问。
过去我发现它们并不完全是线程安全的,并且一些字形相关的操作必须发生在主线程上,并且如果EXC_BAD_ACCESS
不是,则会产生异常或崩溃。 虽然这与您的崩溃报告不完全相同,但这可能是导致崩溃的原因。
要排除跨线程UIKit绘图问题,请将您的调用调用到-drawAtPoint:
到主队列中。
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:unreadChats attributes:attributes];
dispatch_async(dispatch_get_main_queue(), ^{
[attributedString drawAtPoint: labelPosition];
});
我看到的第一件事是你的shadowBlurRadius
没有被设置。 该手册指出:
此属性包含在默认用户坐标空间中测量的模糊半径。 值为0表示没有模糊,而较大的值会产生相应较大的模糊。 默认值是0。
我会尝试用一个非零值来设置它,看看它是否修复你的崩溃。
链接地址: http://www.djcxy.com/p/16715.html上一篇: Mysterious Crash (NSAttributedString, iOS 7)
下一篇: JVM Core Threads