0

NSSetUncaughtExceptionHandler我正在尝试在Rubymotion应用程序中使用全局异常处理程序。而且我不知道该怎么做,可能我使用的 Rubymotion 函数指针语法不正确。

application(application, didFinishLaunchingWithOptions:launchOptions)我有:

NSSetUncaughtExceptionHandler nil do |exception|
  NSLog "exception handler block"
  applicationFailedWithException(exception)
end

和处理程序(从未被调用):

def applicationFailedWithException(exception)
  NSLog "applicationFailedWithException"
end

然后,在运行时,当某个 NoMethodError 发生在异常处理程序块中的某个地方时,也没有调用处理程序方法。我在模拟器和设备上都试过了——没有成功。

PS有没有办法在崩溃日志中获取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
4

3 回答 3

1

迪伦的回答很棒。我非常喜欢像这样的 lambdas 传递方法:

def application(application, didFinishLaunchingWithOptions:launchOptions)
  NSSetUncaughtExceptionHandler method(:on_exception)
end

def on_exception(exception)
  puts "Exception Name: #{exception.name}"
end
于 2014-06-28T01:34:25.120 回答
1

为了让它工作,我必须将一个块分配给一个变量,然后使用该变量:

handler = lambda do |exception|
  NSLog "Exception Name: #{exception.name}"
end
NSSetUncaughtExceptionHandler(handler)

如果我然后在NSException.raise("test", format: "test")REPL 中输入类似的内容,我会看到 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 不能正确保留该块,并且如果您尝试它,应用程序会崩溃而不会出错。

于 2012-09-11T16:33:38.113 回答
0

根据Apple 文档,您必须添加ExceptionHandling.framework到您的项目中。但即使在之后:

Rakefile
Motion::Project::App.setup do |app|
  app.frameworks += %w(ExceptionHandling)
end

它不适用于 OS X。

于 2013-11-19T13:48:06.547 回答