0

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が発生すると、ハンドラメソッドも呼び出されません。シミュレーターとデバイスの両方で試しましたが、成功しませんでした。

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

これを機能させるには、変数にブロックを割り当ててから、その変数を使用する必要がありました。

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%                                                                                 

理論的には、ラムダを最初に変数に割り当てるのではなく、パラメーターとして直接ネストできるはずですが、RubyMotionがブロックを適切に保持しておらず、試してみるとアプリケーションがエラーなしでクラッシュすると思います。

于 2012-09-11T16:33:38.113 に答える
1

ディランの答えは素晴らしいです。私は次のようなラムダとしてメソッドを渡すのが大好きです:

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 に答える
0

Appleのドキュメントによると、プロジェクトに追加ExceptionHandling.frameworkする必要があります。しかし、その後でも:

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

OSXでは機能しません。

于 2013-11-19T13:48:06.547 に答える