iosnstextstorage

NSTextStorage subclass crash upon removing characters


I have a subclass of NSTextStorage that's giving me some issues. I'm getting a crash every time I do the following:

  1. Enter some text on the first line
  2. Hit return to move to the next line
  3. Enter at least two characters
  4. Hit backspace

The error I'm getting is Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'The index -4097 is invalid'

The real problem is that I can't trace the error back to any of my own code. The furthest I can get by debugging is that super.processEditing inside the override of processEditing gets called. The stacktrace isn't giving me anything to work with either.

EDIT: Did some more testing and found out that this only occurs on iOS 9 and newer. Anything on 8 or below doesn't crash.

override func attributesAtIndex(location: Int, effectiveRange range: NSRangePointer) -> [String : AnyObject] {
    return backingStore.attributesAtIndex(location, effectiveRange: range)
}

override func replaceCharactersInRange(range: NSRange, withString str: String) {
    beginEditing()
    backingStore.replaceCharactersInRange(range, withString: str)
    edited([.EditedCharacters, .EditedAttributes], range: range, changeInLength: (str as NSString).length - range.length)
    endEditing()
}

override func setAttributes(attrs: [String : AnyObject]?, range: NSRange) {
    beginEditing()
    backingStore.setAttributes(attrs, range: range)
    edited(.EditedAttributes, range: range, changeInLength: 0)
    endEditing()
}

override func setAttributedString(attrString: NSAttributedString) {
    programmaticChange = true
    super.setAttributedString(attrString)
    programmaticChange = false
}

override func processEditing() {
    if (!programmaticChange &&
        (editedMask.rawValue & NSTextStorageEditActions.EditedCharacters.rawValue) == NSTextStorageEditActions.EditedCharacters.rawValue &&
        changeInLength > 0) {
        doSetAttributesForRange(editedRange)
    }
    print(backingStore)
    super.processEditing()
}

Solution

  • Well, I managed to find something of a workaround though I still have no idea why the crash is happening. It seems to be related to either layout constraints or the size of my rich-text editor's TextView because after I removed the TextView from the storyboard and created it (along with the TextContainer and NSLayoutManager) programatically, the crash no longer occurred.