我的报告中出现了各种崩溃,报告了以下原因:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'failed to generate newParagraphStyle'
发生这种情况的应用确实以编程方式设置了很多属性文本(字体,颜色,有时是段落样式),但我找不到与此直接相关的任何模式。我所看到的几乎所有的报告都包含了堆栈跟踪中某种形式的setLineBreakMode的引用:
-[_UICascadingTextStorage(Accessors) setLineBreakMode:]
我自己从来没有能够重新创建它,但它确实在我的崩溃报告中定期出现。我没有专门在这些地方设置换行模式。有任何想法吗?
编辑:我花了更多的时间研究这个,并找到了一个模式来重现。所以我有一个UITextField,当你点击键盘上的返回时,检测到“/ n”字符,文本字段将重新启动其第一个响应者状态。如果在此之后的任何时候,您尝试修改该字段的文本(或属性文本),它会崩溃。有一个关键元素,只有在设置了typingAttributes时才会发生。他们的目标并不重要。
我尝试了一切,在设置文本之前将typingAttributes设置为nil,设置一个固定的字符串以确保它不是我们设置的 - 没有运气。总是崩溃。一旦你进入这种状态,文本字段就会被打破。避免它的黑客就是吹走文本域并创建一个新文本 - 但就是这样。一个黑客。
一些更有趣的信息,代码检测返回键的方式写得不好 - 它检测到“/ n”并返回NO:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
它没有使用适当的方法:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
在应用程序的一个地方,这实际上修复了崩溃,在其他地方,它总是使用正确的方法,崩溃仍在发生。唯一的解决方法是吹走文本域并创建一个新文本域。对我来说,这似乎是iOS本身的一个错误。
我刚刚遇到这个问题,并且能够通过在typingAttributes
被相同的textField
调用之前直接将有问题的nil
的resignFirstResponder
设置为textField
来解决它。
Frankie的解决方案有所帮助,但仍然发现触发此错误的边缘情况:
** Assertion failure in -[_UICascadingTextStorage setLineBreakMode:],
/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.30.14/TextSystem/_UICascadingTextStorage.m:292
我的解决方案是子类UITextField并添加hackTextAttributes属性:
import UIKit
class HackTF: UITextField {
var hackTextAttributes: [String: AnyObject]
init(frame: CGRect, textAttributes: [String: AnyObject]) {
hackTextAttributes = textAttributes
super.init(frame: frame)
delegate = self
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func hackSetText(text: String) {
attributedText = NSAttributedString(string: text, attributes: hackTextAttributes)
}
func hackSetAttributedText(text: String, attributes: [String: AnyObject]) {
hackTextAttributes = attributes
hackSetText(text)
}
}
extension HackTF: UITextFieldDelegate {
func textFieldDidBeginEditing(textField: UITextField) {
typingAttributes = hackTextAttributes // Make sure fields with no text have appropriate typingAttributes
}
}
// MARK: Apple Crash Prevention Hack
extension HackTF {
override func resignFirstResponder() -> Bool {
var isResigningHack = false
if self.text?.length == 0 { // if no text, add some text so we won't crash...
isResigningHack = true
attributedText = NSAttributedString(string: " ", attributes: hackTextAttributes)
}
typingAttributes = nil
let resign = super.resignFirstResponder()
if isResigningHack { // clear the text
attributedText = NSAttributedString(string: "", attributes: hackTextAttributes)
}
return resign
}
}
也许这会对某人有所帮助。我能够通过一个简单的文本字段子类来修复崩溃,其灵感来自mcm's solution。
class VLAttributedTextField: UITextField {
override func resignFirstResponder() -> Bool {
self.typingAttributes = self.defaultTextAttributes
let resign = super.resignFirstResponder()
return resign
}
}
如上所述,将typingAttributes设置为nil(或空字典)不起作用。
在文本字段中设置typingAttributes只是故事的一半。如果您在UITextField上设置了委托,则也将其取消。我需要两个让这个崩溃消失。