我试图在Rubymotion应用程序中使用NSSetUncaughtExceptionHandler
连接全局异常处理程序。而且我不知道该怎么做,可能是我错误地使用了Rubymotion函数指针语法。
在application(application, didFinishLaunchingWithOptions:launchOptions)
中,我有:
NSSetUncaughtExceptionHandler nil do |exception|
NSLog "exception handler block"
applicationFailedWithException(exception)
end
和处理程序(从未调用过):
def applicationFailedWithException(exception)
NSLog "applicationFailedWithException"
end
然后,在运行时,当某个NoMethodError发生在某处时,异常处理程序块和处理程序方法均未调用。我已经在模拟器和设备上都尝试过-没有成功。
附言有没有办法在崩溃日志中获取ruby方法堆栈,崩溃日志中的最后一个应用程序方法始终是
rb_rb2oc_exc_handler
而不是特定于应用程序的方法,这很奇怪。谢谢
更新2015
似乎,使用较新版本的Rubymotion,您必须将对处理程序的引用保存在实例变量中,否则将无法正常工作。所以它应该看起来像:
def application(application, didFinishLaunchingWithOptions:launchOptions)
@exceptionHandler = lambda { |exception| uncaughtExceptionHandler(exception) }
# or you can use a method reference, which is the same
# @exceptionHandler = method :uncaughtExceptionHandler
NSSetUncaughtExceptionHandler @exceptionHandler
...
end
def uncaughtExceptionHandler(exception)
# log it or send it to crashlytics / flurry / whatever
NSLog "Fatal exception catched\nName: #{exception.name}\nReason: # {exception.reason}\nInfo#{exception.userInfo}"
end
最佳答案
为了使它起作用,我必须为一个变量分配一个块,然后使用该变量:
handler = lambda do |exception|
NSLog "Exception Name: #{exception.name}"
end
NSSetUncaughtExceptionHandler(handler)
如果我随后在REPL中打入
NSException.raise("test", format: "test")
之类的东西,我会看到NSLog就是这样:2012-09-11 09:33:05.949 exc[14723:c07] Exception Name: test
2012-09-11 09:33:05.950 exc[14723:c07] *** Terminating app due to uncaught exception 'test', reason: 'test'
*** First throw call stack:
(0x1647022 0x22bcd6 0x15efa48 0x15ef9b9 0x8f00743 0xe3c0c 0x8f0031a 0x8f000ad 0xd4c9fa2 0x259e8d9 0x259f509 0x157e803 0x157dd84 0x157dc9b 0x261f7d8 0x261f88a 0x563626 0x25d0 0x23b5)
terminate called throwing an exception%
从理论上讲,您应该能够直接将lambda嵌套为参数,而不是先将其分配给变量,但是我认为RubyMotion不会正确保留该块,并且如果您尝试使用它,应用程序也会崩溃而不会出错。