仅在 iPhone 5C 上滚动 UITableView 会导致异常和崩溃
Posted
技术标签:
【中文标题】仅在 iPhone 5C 上滚动 UITableView 会导致异常和崩溃【英文标题】:Scrolling through UITableView causes Exception and Crash only on iPhone 5C 【发布时间】:2014-09-09 15:35:40 【问题描述】:当用户滚动浏览我的UITableView
太快或点击状态栏跳到表格顶部时,会引发异常。我只在 iPhone 5C 设备上看到此崩溃。 4S、5、32位模拟器都无法重现。
使用“所有异常”断点,我能够打印出我可以通过崩溃增加帧指针的所有回溯。因为在回溯中没有我的应用程序的痕迹(除了主要的),我认为这是一个 Apple 错误,与 [NSRLEArray objectAtIndex:effectiveRange:]
有关。 this 问题的作者似乎对 OS X 应用程序也有同样的问题,并且有一条评论建议查看我的应用程序中的 NSAttributedString
用法。我确实在我的表格视图单元格中使用NSAttributedStrings
来超链接UITextView
中的某些字符串。但如果是NSAttributedString
的普遍问题,这不会也导致其他 ios 设备崩溃吗?
回溯:
(lldb) bt
* thread #1: tid = 0x2e57bd, 0x3978e6a0 libobjc.A.dylib`objc_exception_throw, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x3978e6a0 libobjc.A.dylib`objc_exception_throw
frame #1: 0x2f431dc4 CoreFoundation`+[NSException raise:format:] + 112
frame #2: 0x2fd55230 Foundation`-[NSRLEArray objectAtIndex:effectiveRange:] + 120
frame #3: 0x2fd71d76 Foundation`-[NSConcreteMutableAttributedString addAttribute:value:range:] + 198
frame #4: 0x36d7b278 UIFoundation`__50-[NSConcreteTextStorage addAttribute:value:range:]_block_invoke + 156
frame #5: 0x36d7b102 UIFoundation`-[NSConcreteTextStorage addAttribute:value:range:] + 170
frame #6: 0x337fc02e DataDetectorsUI`-[DDTextKitOperation _addResultsToAttributes] + 266
frame #7: 0x337fc1d6 DataDetectorsUI`__46-[DDTextKitOperation doURLificationOnDocument]_block_invoke_2 + 26
frame #8: 0x36d79a5e UIFoundation`-[NSTextStorage(ActorSupport) coordinateAccess:] + 34
frame #9: 0x337fc1b8 DataDetectorsUI`__46-[DDTextKitOperation doURLificationOnDocument]_block_invoke + 116
frame #10: 0x39c78bde libdispatch.dylib`_dispatch_barrier_sync_f_slow_invoke + 66
frame #11: 0x39c730ae libdispatch.dylib`_dispatch_client_callout + 22
frame #12: 0x39c759a8 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 268
frame #13: 0x2f3fc5b0 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
frame #14: 0x2f3fae7c CoreFoundation`__CFRunLoopRun + 1308
frame #15: 0x2f365470 CoreFoundation`CFRunLoopRunSpecific + 524
frame #16: 0x2f365252 CoreFoundation`CFRunLoopRunInMode + 106
frame #17: 0x3409f2ea GraphicsServices`GSEventRunModal + 138
frame #18: 0x31c1a844 UIKit`UIApplicationMain + 1136
* frame #19: 0x000bffb4 [AppName]`main(argc=1, argv=0x27d4ecec) + 116 at main.m:16
(lldb) bt
* thread #1: tid = 0x2e57bd, 0x39153994 libc++abi.dylib`__cxa_throw, queue = 'com.apple.main-thread', stop reason = breakpoint 1.2
frame #0: 0x39153994 libc++abi.dylib`__cxa_throw
frame #1: 0x3978e79a libobjc.A.dylib`objc_exception_throw + 250
frame #2: 0x2f431dc4 CoreFoundation`+[NSException raise:format:] + 112
frame #3: 0x2fd55230 Foundation`-[NSRLEArray objectAtIndex:effectiveRange:] + 120
frame #4: 0x2fd71d76 Foundation`-[NSConcreteMutableAttributedString addAttribute:value:range:] + 198
frame #5: 0x36d7b278 UIFoundation`__50-[NSConcreteTextStorage addAttribute:value:range:]_block_invoke + 156
frame #6: 0x36d7b102 UIFoundation`-[NSConcreteTextStorage addAttribute:value:range:] + 170
frame #7: 0x337fc02e DataDetectorsUI`-[DDTextKitOperation _addResultsToAttributes] + 266
frame #8: 0x337fc1d6 DataDetectorsUI`__46-[DDTextKitOperation doURLificationOnDocument]_block_invoke_2 + 26
frame #9: 0x36d79a5e UIFoundation`-[NSTextStorage(ActorSupport) coordinateAccess:] + 34
frame #10: 0x337fc1b8 DataDetectorsUI`__46-[DDTextKitOperation doURLificationOnDocument]_block_invoke + 116
frame #11: 0x39c78bde libdispatch.dylib`_dispatch_barrier_sync_f_slow_invoke + 66
frame #12: 0x39c730ae libdispatch.dylib`_dispatch_client_callout + 22
frame #13: 0x39c759a8 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 268
frame #14: 0x2f3fc5b0 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
frame #15: 0x2f3fae7c CoreFoundation`__CFRunLoopRun + 1308
frame #16: 0x2f365470 CoreFoundation`CFRunLoopRunSpecific + 524
frame #17: 0x2f365252 CoreFoundation`CFRunLoopRunInMode + 106
frame #18: 0x3409f2ea GraphicsServices`GSEventRunModal + 138
frame #19: 0x31c1a844 UIKit`UIApplicationMain + 1136
* frame #20: 0x000bffb4 [AppName]`main(argc=1, argv=0x27d4ecec) + 116 at main.m:16
(lldb) bt
* thread #1: tid = 0x2e57bd, 0x3978e6a0 libobjc.A.dylib`objc_exception_throw, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x3978e6a0 libobjc.A.dylib`objc_exception_throw
frame #1: 0x2f431b88 CoreFoundation`-[NSException raise] + 8
frame #2: 0x36d7b19a UIFoundation`-[NSConcreteTextStorage addAttribute:value:range:] + 322
frame #3: 0x337fc02e DataDetectorsUI`-[DDTextKitOperation _addResultsToAttributes] + 266
frame #4: 0x337fc1d6 DataDetectorsUI`__46-[DDTextKitOperation doURLificationOnDocument]_block_invoke_2 + 26
frame #5: 0x36d79a5e UIFoundation`-[NSTextStorage(ActorSupport) coordinateAccess:] + 34
frame #6: 0x337fc1b8 DataDetectorsUI`__46-[DDTextKitOperation doURLificationOnDocument]_block_invoke + 116
frame #7: 0x39c78bde libdispatch.dylib`_dispatch_barrier_sync_f_slow_invoke + 66
frame #8: 0x39c730ae libdispatch.dylib`_dispatch_client_callout + 22
frame #9: 0x39c759a8 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 268
frame #10: 0x2f3fc5b0 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
frame #11: 0x2f3fae7c CoreFoundation`__CFRunLoopRun + 1308
frame #12: 0x2f365470 CoreFoundation`CFRunLoopRunSpecific + 524
frame #13: 0x2f365252 CoreFoundation`CFRunLoopRunInMode + 106
frame #14: 0x3409f2ea GraphicsServices`GSEventRunModal + 138
frame #15: 0x31c1a844 UIKit`UIApplicationMain + 1136
* frame #16: 0x000bffb4 [AppName]`main(argc=1, argv=0x27d4ecec) + 116 at main.m:16
(lldb) bt
* thread #1: tid = 0x2e57bd, 0x39153994 libc++abi.dylib`__cxa_throw, queue = 'com.apple.main-thread', stop reason = breakpoint 1.2
frame #0: 0x39153994 libc++abi.dylib`__cxa_throw
frame #1: 0x3978e79a libobjc.A.dylib`objc_exception_throw + 250
frame #2: 0x2f431b88 CoreFoundation`-[NSException raise] + 8
frame #3: 0x36d7b19a UIFoundation`-[NSConcreteTextStorage addAttribute:value:range:] + 322
frame #4: 0x337fc02e DataDetectorsUI`-[DDTextKitOperation _addResultsToAttributes] + 266
frame #5: 0x337fc1d6 DataDetectorsUI`__46-[DDTextKitOperation doURLificationOnDocument]_block_invoke_2 + 26
frame #6: 0x36d79a5e UIFoundation`-[NSTextStorage(ActorSupport) coordinateAccess:] + 34
frame #7: 0x337fc1b8 DataDetectorsUI`__46-[DDTextKitOperation doURLificationOnDocument]_block_invoke + 116
frame #8: 0x39c78bde libdispatch.dylib`_dispatch_barrier_sync_f_slow_invoke + 66
frame #9: 0x39c730ae libdispatch.dylib`_dispatch_client_callout + 22
frame #10: 0x39c759a8 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 268
frame #11: 0x2f3fc5b0 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
frame #12: 0x2f3fae7c CoreFoundation`__CFRunLoopRun + 1308
frame #13: 0x2f365470 CoreFoundation`CFRunLoopRunSpecific + 524
frame #14: 0x2f365252 CoreFoundation`CFRunLoopRunInMode + 106
frame #15: 0x3409f2ea GraphicsServices`GSEventRunModal + 138
frame #16: 0x31c1a844 UIKit`UIApplicationMain + 1136
* frame #17: 0x000bffb4 [AppName]`main(argc=1, argv=0x27d4ecec) + 116 at main.m:16
(lldb) bt
* thread #1: tid = 0x2e57bd, 0x39d3e1fc libsystem_kernel.dylib`__pthread_kill + 8, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
frame #0: 0x39d3e1fc libsystem_kernel.dylib`__pthread_kill + 8
frame #1: 0x39da5a52 libsystem_pthread.dylib`pthread_kill + 58
frame #2: 0x39cef02c libsystem_c.dylib`abort + 76
frame #3: 0x001f32ba [AppName]`uncaught_exception_handler + 26
frame #4: 0x2f432184 CoreFoundation`__handleUncaughtException + 580
frame #5: 0x3978e926 libobjc.A.dylib`_objc_terminate() + 174
frame #6: 0x391541b2 libc++abi.dylib`std::__terminate(void (*)()) + 78
frame #7: 0x39153d16 libc++abi.dylib`__cxa_rethrow + 102
frame #8: 0x3978e80e libobjc.A.dylib`objc_exception_rethrow + 42
frame #9: 0x36d7b150 UIFoundation`-[NSConcreteTextStorage addAttribute:value:range:] + 248
frame #10: 0x337fc02e DataDetectorsUI`-[DDTextKitOperation _addResultsToAttributes] + 266
frame #11: 0x337fc1d6 DataDetectorsUI`__46-[DDTextKitOperation doURLificationOnDocument]_block_invoke_2 + 26
frame #12: 0x36d79a5e UIFoundation`-[NSTextStorage(ActorSupport) coordinateAccess:] + 34
frame #13: 0x337fc1b8 DataDetectorsUI`__46-[DDTextKitOperation doURLificationOnDocument]_block_invoke + 116
frame #14: 0x39c78bde libdispatch.dylib`_dispatch_barrier_sync_f_slow_invoke + 66
frame #15: 0x39c730ae libdispatch.dylib`_dispatch_client_callout + 22
frame #16: 0x39c759a8 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 268
frame #17: 0x2f3fc5b0 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
frame #18: 0x2f3fae7c CoreFoundation`__CFRunLoopRun + 1308
frame #19: 0x2f365470 CoreFoundation`CFRunLoopRunSpecific + 524
frame #20: 0x2f365252 CoreFoundation`CFRunLoopRunInMode + 106
frame #21: 0x3409f2ea GraphicsServices`GSEventRunModal + 138
frame #22: 0x31c1a844 UIKit`UIApplicationMain + 1136
* frame #23: 0x000bffb4 [AppName]`main(argc=1, argv=0x27d4ecec) + 116 at main.m:16
(lldb) bt
* thread #22: tid = 0x2e57ea, 0x39da2cbc libsystem_pthread.dylib`start_wqthread, stop reason = signal SIGABRT
* frame #0: 0x39da2cbc libsystem_pthread.dylib`start_wqthread
这里是我设置属性字符串的地方:
// earlier in the code
tweetTextView.attributedText = [[NSAttributedString alloc] initWithString:tweetTextView.text];
...
-(void)findHashtagsAndAtMentionsInTweetText:(UITextView *)textView
NSString *tweetText = textView.text;
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(@(\\w+))|(^|\\W)(#|\\uFF03)(\\w*\\pL\\w*)" options:0 error:&error];
NSArray *matches = [regex matchesInString:tweetText options:0 range:NSMakeRange(0, tweetText.length)];
NSMutableAttributedString * myTagOrMention = [[NSMutableAttributedString alloc] initWithString:tweetTextView.text];
for (NSTextCheckingResult *match in matches)
NSRange wordRange = [match rangeAtIndex:0]; // causing crash?
NSString* word = [tweetText substringWithRange:wordRange];
if([word rangeOfString:@"@"].location != NSNotFound)
// @ mention
// remove whitespaces and @
NSString *formattedTag = [NSString stringWithFormat:@"%@", [[word stringByReplacingOccurrencesOfString:@" " withString:@""] stringByReplacingOccurrencesOfString:@"@" withString:@""]];
NSString *tweetContets = tweetTextView.text;
NSRange range = [tweetContets rangeOfString:word];
if([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"twitter://"]])
NSString *twitterAppURL = [NSString stringWithFormat:@"%@%@", @"twitter://user?screen_name=",formattedTag];
[myTagOrMention addAttribute:NSLinkAttributeName value:twitterAppURL range:range];
else
[myTagOrMention addAttribute:NSLinkAttributeName value:[NSString stringWithFormat:@"%@%@", @"http://mobile.twitter.com/",formattedTag] range:range];
tweetTextView.attributedText = myTagOrMention;
else
// hashtag
// remove whitespaces and pound
NSString *formattedTag = [NSString stringWithFormat:@"%@", [[word stringByReplacingOccurrencesOfString:@" " withString:@""] stringByReplacingOccurrencesOfString:@"#" withString:@""]];
NSString *tweetContets = tweetTextView.text;
NSRange range = [tweetContets rangeOfString:word];
[myTagOrMention addAttribute:NSLinkAttributeName value:[NSString stringWithFormat:@"%@%@%@%@", @"http://twitter.com/search/", @"?q=%23", formattedTag, @"&s=hash"] range:range];
tweetTextView.attributedText = myTagOrMention;
【问题讨论】:
我相信这个问题有可取之处,应该重新打开。我有另一个用户尝试在此处就有关此问题的其他问题与我联系:***.com/questions/24620330/… 要重新打开它,您应该: 包含重现此崩溃所需的最少代码量;将问题从“对这个令人费解的崩溃的任何帮助都会非常感激”改进为重申您的实际问题的问题。 @GeorgeStocker 谢谢你,抱歉耽搁了。这是一个我不再参与的旧项目,不得不挖掘代码和 QA 设备。我已编辑问题以反映发生问题的代码块。 【参考方案1】:错误不在您发布的代码中。该错误发生在 UITextView
在其链接仍在生成时被重用,这是异步完成的。
查看这些类似的 Stack Overflow 问题:
iOS 7 UITextView link detection crash in UITableView UITextViews in a UITableView link detection bug in iOS 7 UITextView link detection in iOS 7许多用户报告说,在单元格的 prepareForReuse
方法中将文本视图的文本属性设置为 nil
可以解决此问题。或者,您可以使用 TTTAttributedLabel
之类的库来代替文本视图。
它只出现在 iPhone 5C 上的事实可能是red herring。我敢打赌这台设备仍在运行 iOS 7,而其他设备已更新到更新的 iOS 版本。
附带说明,您的正则表达式可能未涵盖某些极端情况。我会删除你的推特解析方法并用the official twitter-text-objc
library替换它。
【讨论】:
这是一个很好的答案,非常感谢您抽出宝贵时间回答这个问题。当时所有设备都运行 iOS 7(这是在 iOS 8 发布之前),我无法在运行 iOS 8.1 的 5C 设备上重现崩溃。这是我们正在迁移到 iOS 7 SDK 的一个非常古老的项目,我怀疑我是否会继续研究它。我将暂时将此答案标记为已接受,实施更改,并在我有任何其他问题时发表评论。再次感谢。 @JAL 在 prepareForReuse 中将 text 设置为 nil 是否解决了问题?以上是关于仅在 iPhone 5C 上滚动 UITableView 会导致异常和崩溃的主要内容,如果未能解决你的问题,请参考以下文章