简体   繁体   中英

Why does this call to NSMutableAttributedString addAttributes crash?

I'm getting a frequent crash on calling addAttributes out in the field that I can't reproduce (EXC_BREAKPOINT). Have added checks on the NSRange I'm passing in and surprisingly it still crashes... any ideas very gratefully received!

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)
}

Crash log added by request:

#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

As the crash is not easily reproducible, it should depend on the contents of myAttributedString , or nsrange : The surrounding code provides values that pass your checks, but still crash. There are two ways I am aware of how to achieve that.

The first is by passing an NSRange that has location NSNotFound and length > 0 . Example:

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

The second is a crash in older iOS versions when adding attributes to a subset of an emoji. If you only see crashes in older iOS versions, it should be a scenario like this one:

let myAttributedString = NSMutableAttributedString(string: "👨‍👩‍👧 is a family")
let nsrange = NSRange(location: 1, length: 2)

So if you see the crash for all iOS versions, you can check for nsrange != NSNotFound first to fix the crash. If you see the crash only for older iOS versions, then check the surrounding code for places where you could calculate a wrong range. This typically happens when mixing string info from Swift with string info from Objective-C's Foundation. For instance, "👨‍👩‍👧".count is 1, whereas ("👨‍👩‍👧" as NSString).length is 8.

First of all need to be sure that cellStyle.boldFont() return correct value. Try to use UIFont.boldSystemFont(ofSize: 15) to be sure that you have correct value in 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)
}

After that, double re-check that myAttributedString is NSMutableAttributedString class using runtime debugger. Maybe it is immutable NSAttributedString and you trying to add your attributes to it...

After that, if you still have crash, need to check nsrange value. Maybe you have nil or some incorrect value there

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM