2013-03-11 56 views
6

我正在使用Racket Objective-C FFI在應用中嵌入WebKit WebView。球拍Objective-C FFI--避免重新定義類

爲了接收頁面加載通知,我在Racket中創建了一個新的ObjC類,它被設置爲網絡視圖的幀加載代理。

類看起來類似:

(define-objc-class MyWebFrameLoadDelegate NSObject 
    [] 
    (- _void (webView: [_id wv] didFinishLoadForFrame: [_id wf]) 
    (send frame set-status-text "Page Loaded"))) 

當運行中DrRacket它的偉大工程的第一次的代碼。此外迭代導致進程死:

Exception Type: EXC_BAD_ACCESS (SIGSEGV) 
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000020 
... 
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 
0 libobjc.A.dylib     0x00007fff8511e299 objc_registerClassPair + 63 
1 Racket       0x00000001002d329c ffi_call_unix64 + 76 
2 Racket       0x00000001002d3eb4 ffi_call + 644 
3 Racket       0x00000001002c612f ffi_do_call + 1599 
4 ???        0x00000001004b50cc 0 + 4299903180 
... 

...這似乎表明它是ObjC類,它是事業的重新定義。

有沒有一種乾淨的方式使用FFI或更一般的球拍功能,以避免重新定義類,如果它已經存在?

我試圖在條件中包裝define-objc-class,但它需要是一個頂級的形式。

我可以下拉到原始的ObjC運行時功能並在運行中定義委託類 - 但它可以很好地避免這種情況。


解決方案 - 包裝在letdefine-objc-class在嵌套範圍內定義條件的類:

(define MyWebFrameLoadDelegate 
    (or (objc_lookUpClass "MyWebFrameLoadDelegate") 
     (let() 
     (define-objc-class MyWebFrameLoadDelegate NSObject 
      [] 
      (- _void (webView: [_id wv] didFinishLoadForFrame: [_id wf]) 
      (send frame set-status-text "Page Loaded"))) 
     MyWebFrameLoadDelegate))) 
+0

試驗平臺的完整的源:https://gist.github.com/nickmain/5136923 – 2013-03-11 19:25:40

回答

4

我不認爲define-obj-class必須在頂層使用。不過,這是一種定義形式,因此您不能將其用作表達式。你應該能夠做到像下面這樣:

(define MyClass 
    (or ___ ;; find the class, if it already exists 
     (let() 
     (define-objc-class MyClass ___) 
     MyClass))) 

順便說一句,它看起來像轟然行爲的修復承諾在3月7日

+0

非常感謝 - 這工作! – 2013-03-11 21:08:31