为什么对NSMutableAttributedString addAttributes的调用会崩溃?

时间:2018-06-28 11:50:01

标签: ios swift nsattributedstring core-text

在无法复制的字段(EXC_BREAKPOINT)上呼出addAttributes时,我经常崩溃。在我传递的NSRange上添加了检查,令人惊讶的是它仍然崩溃...非常感谢收到任何想法!

let boldAttributes : [NSAttributedStringKey: Any] = [.font: cellStyle.boldFont()]
if (nsrange.location >= 0 && nsrange.length > 0 && nsrange.location + nsrange.length <= myAttributedString.length) {
    myAttributedString.addAttributes(boldAttributes, range: nsrange)
}

根据请求添加的崩溃日志:

#0. Crashed: com.apple.main-thread
0  MyApp                   0x10054ae38 specialized UIAccessorizedTextField.accessoryAttributedString(IndexPath, cellStyle : UIAccessorizedTextFieldCellStyle) -> NSAttributedString (UIAccessorizedTextField.swift:322)
1  MyApp                   0x10054b104 specialized UIAccessorizedTextField.collectionView(UICollectionView, cellForItemAt : IndexPath) -> UICollectionViewCell (UIAccessorizedTextField.swift:345)
2  MyApp                   0x10054860c @objc UIAccessorizedTextField.collectionView(UICollectionView, cellForItemAt : IndexPath) -> UICollectionViewCell (UIAccessorizedTextField.swift)
3  UIKit                          0x18b229f3c -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:] + 356
4  UIKit                          0x18bb90b68 -[UICollectionView _prefetchItemsForVelocity:maxItemsToPrefetch:invalidateCandidatesOnDirectionChanges:] + 508
5  UIKit                          0x18b2088b4 -[UICollectionView layoutSubviews] + 760
6  UIKit                          0x18b0d76f4 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1420
7  QuartzCore                     0x18564dfec -[CALayer layoutSublayers] + 184
8  QuartzCore                     0x18565217c CA::Layer::layout_if_needed(CA::Transaction*) + 324
9  QuartzCore                     0x1855be830 CA::Context::commit_transaction(CA::Transaction*) + 320
10 QuartzCore                     0x1855e6364 CA::Transaction::commit() + 580
11 QuartzCore                     0x1855e71e4 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 92
12 CoreFoundation                 0x18146e910 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
13 CoreFoundation                 0x18146c238 __CFRunLoopDoObservers + 412
14 CoreFoundation                 0x18146c884 __CFRunLoopRun + 1436
15 CoreFoundation                 0x18138cda8 CFRunLoopRunSpecific + 552
16 GraphicsServices               0x183371020 GSEventRunModal + 100
17 UIKit                          0x18b3a9758 UIApplicationMain + 236
18 MyApp                   0x1003f2830 main (main.m:16)
19 libdyld.dylib                  0x180e1dfc0 start + 4

2 个答案:

答案 0 :(得分:2)

由于崩溃不容易重现,因此应取决于myAttributedStringnsrange的内容:周围的代码提供了可通过检查但仍然崩溃的值。我知道有两种实现方法。

第一个方法是传递位置为NSRangeNSNotFound的{​​{1}}。示例:

length > 0

第二个是在向表情符号的子集添加属性时在较旧的iOS版本中崩溃。如果您仅在较旧的iOS版本中看到崩溃,则应该是这种情况:

let myAttributedString = NSMutableAttributedString(string: "Hello")
let nsrange = NSRange(location: NSNotFound, length: 1)

因此,如果您看到所有iOS版本的崩溃,都可以先检查let myAttributedString = NSMutableAttributedString(string: "‍‍ is a family") let nsrange = NSRange(location: 1, length: 2) 来修复崩溃。如果您仅在较旧的iOS版本上看到崩溃,则请检查周围的代码,找出可以计算错误范围的位置。当将Swift中的字符串信息与Objective-C基金会的字符串信息混合时,通常会发生这种情况。例如,nsrange != NSNotFound为1,而"‍‍".count为8。

答案 1 :(得分:0)

首先,需要确保cellStyle.boldFont()返回正确的值。 尝试使用UIFont.boldSystemFont(ofSize: 15)以确保您在boldAttributes中具有正确的值

let boldAttributes : [NSAttributedStringKey: Any] = [.font: UIFont.boldSystemFont(ofSize: 15)]
if (nsrange.location >= 0 && nsrange.length > 0 && nsrange.location + nsrange.length <= myAttributedString.length) {
    myAttributedString.addAttributes(boldAttributes, range: nsrange)
}

然后,使用运行时调试器重新检查myAttributedStringNSMutableAttributedString类。 也许它是不可变的NSAttributedString,而您尝试向其中添加属性...

此后,如果您仍然崩溃,则需要检查nsrange的值。也许您那里有nil或一些不正确的值