编辑:在问题前加上"Method Swizzle Crash"来帮助其他人找到bug。
对于在模拟器或任何运行iOS 4或更高版本的设备上按下的越南语键盘上的每个键,将向控制台打印以下消息,并且不会向第一响者发送任何字符:
Can't find transliterator file: vi_TelexTransliterator
utrans_transUChars error U_ILLEGAL_ARGUMENT_ERROR
在我的服务器或客户端代码中没有这些字符串或子字符串的实例。这是来自API的
模拟器和运行iOS 4的设备将在第二次按键时持续崩溃。iOS 5没有崩溃问题。调用堆栈顶部的错误如下所示:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFString substringToIndex:]: Range or index out of bounds'
调用栈是这样的:
Foundation -[NSString substringToIndex:]
TextInput -[TIKeyboardInputManagerZephyr internalIndexToExternal:]
TextInput -[TIKeyboardInputManagerZephyr inputCount]
UIKit -[UIKeyboardImpl addInputString:fromVariantKey:]
UIKit -[UIKeyboardImpl handleStringInput:fromVariantKey:]
UIKit -[UIKeyboardImpl handleKeyEvent:]
UIKit -[UIApplication _handleKeyEvent:]
UIKit -[UIResponder(Internal) _handleKeyEvent:]
UIKit -[UIResponder(Internal) _handleKeyEvent:]
UIKit -[UIResponder(Internal) _handleKeyEvent:]
UIKit -[UIResponder(Internal) _handleKeyEvent:]
UIKit -[UIResponder(Internal) _handleKeyEvent:]
UIKit -[UIResponder(Internal) _handleKeyEvent:]
UIKit -[UIResponder(Internal) _handleKeyEvent:]
UIKit -[UIResponder(Internal) _handleKeyEvent:]
UIKit -[UIResponder(Internal) _handleKeyEvent:]
UIKit -[UIResponder(Internal) _handleKeyEvent:]
UIKit -[UIApplication handleKeyEvent:]
UIKit -[UIKeyboardLayoutStar sendStringAction:forKey:]
UIKit -[UIKeyboardLayoutStar touchUp:]
UIKit -[UIKeyboardLayout touchesEnded:withEvent:]
UIKit -[UIWindow _sendTouchesForEvent:]
UIKit -[UIWindow sendEvent:]
UIKit -[UIApplication sendEvent:]
UIKit _UIApplicationHandleEvent
GraphicsServices PurpleEventCallback
CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__
CoreFoundation __CFRunLoopDoSource1
CoreFoundation __CFRunLoopRun
CoreFoundation CFRunLoopRunSpecific
CoreFoundation CFRunLoopRunInMode
GraphicsServices GSEventRunModal
GraphicsServices GSEventRun
UIKit -[UIApplication _run]
UIKit UIApplicationMain
APP main (main.m:XXX)
我在整个应用程序的不同位置尝试过这个键盘,包括在加载主视图之前的安全屏幕上,以及在其委托中注释掉我们所有的输入处理方法。失败是一致的。当实现委托方法时,我步进textField:shouldChangeCharactersInRange:replacementString:,接收到的字符串是有效的。
一切似乎都表明这是苹果的问题,但我在网上没有找到其他关于这个问题的报告。我的直觉告诉我这是我的代码。谁能给点提示吗?
这个答案中的信息对那些在使用方法混合时遇到类似问题的人最有用。有关swizzling方法的说明,请参阅此处。
我在NSBundle中为我自己的方法添加了pathForResource:ofType:用于搜索我的应用程序加载的每个bundle。它还会搜索我随应用一起发布的资源档案。现在的问题是:键盘通常会访问iOS内部私有包中的数据。我的swizzed方法无法访问这些,所以键盘会间歇性地失败,并且没有给我任何有用的信息来解释为什么。
为了解决这个问题,我改变了swizzled方法,这样它就会调用[NSBundle pathForResource:ofType:]的原始实现,如果我的应用程序的方法不能找到资源。
解决问题。