简体   繁体   中英

iOS15 UITextView After dragging the view, it causes a crash, Invalid parameter not satisfying: pos

crash example

The above article is a problem found by a netizen on the forum. Recently, I also found a similar crash stack on firebase. I guess it is also caused by this reason, and it may be the problem of data out of bounds. Do you have a good solution?

Firebase crashed the stack:

Fatal Exception: NSInternalInconsistencyException
Invalid parameter not satisfying: pos
0
CoreFoundation
__exceptionPreprocess
1
libobjc.A.dylib
objc_exception_throw
2
Foundation
_userInfoForFileAndLine
3
UIKitCore
-[_UITextKitTextPosition compare:]
4
UIKitCore
-[UITextInputController comparePosition:toPosition:]
5
UIKitCore
-[UITextView comparePosition:toPosition:]
6
UIKitCore
-[UITextPasteController _clampRange:]
7
UIKitCore
__87-[UITextPasteController _performPasteOfAttributedString:toRange:forSession:completion:]_block_invoke
8
UIKitCore
__87-[UITextPasteController _performPasteOfAttributedString:toRange:forSession:completion:]_block_invoke.177
9
UIKitCore
-[UITextInputController _pasteAttributedString:toRange:completion:]
10
UIKitCore
-[UITextPasteController _performPasteOfAttributedString:toRange:forSession:completion:]
11
UIKitCore
__49-[UITextPasteController _executePasteForSession:]_block_invoke
12
libdispatch.dylib
_dispatch_call_block_and_release
13
libdispatch.dylib
_dispatch_client_callout
14
libdispatch.dylib
_dispatch_main_queue_callback_4CF
15
CoreFoundation
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
16
CoreFoundation
__CFRunLoopRun
17
CoreFoundation
CFRunLoopRunSpecific
18
GraphicsServices
GSEventRunModal
19
UIKitCore
-[UIApplication _run]
20
UIKitCore
UIApplicationMain
21
HelloTalk_Binary
main.m -  20 
main + 20

I could not find the reason, but found work around. If I implement one of the two methods of UITextPasteDelegate for UITextView , textPasteConfigurationSupporting or performPasteOf , to return string without any attributes, then app does not crash.

public func textPasteConfigurationSupporting(
  _ textPasteConfigurationSupporting: UITextPasteConfigurationSupporting,
  performPasteOf attributedString: NSAttributedString,
  to textRange: UITextRange
) -> UITextRange {
  let start = textView.offset(from: textView.beginningOfDocument, to: textRange.start)
  let length = textView.offset(from: textRange.start, to: textRange.end)
  let nsRange = NSRange(location: start, length: length)

  let shouldInsert = textView(
   textView,
   shouldChangeTextIn: nsRange,
   replacementText: attributedString.string
  )

  if shouldInsert {
   textView.replace(textRange, withText: attributedString.string)
  }

  return textRange
}

or

public func textPasteConfigurationSupporting(
  _ textPasteConfigurationSupporting: UITextPasteConfigurationSupporting,
  combineItemAttributedStrings itemStrings: [NSAttributedString],
  for textRange: UITextRange
) -> NSAttributedString {
  return NSAttributedString(string: itemStrings.map { $0.string }.joined())
}

@Sibcat has a good catch.

The documentations for the method textPasteConfigurationSupporting:performPasteOfAttributedString:toRange: says that if you implement this method - no system mechanizm be applied (where the crash occurs)

It this is not implemented, the standard paste mechanism will be used. So just implementing this method the app is protected from the crash.

Additional note

The crash occurs only if you return NO as answer from delegate method textView:shouldChangeTextInRange:replacementText:text

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