2013-03-11 3 views
6

Sto utilizzando l'Objectet-C FFI Racket per incorporare una WebView WebView in un'app.Racket Objective-C FFI - evitare la ridefinizione di una classe

Per ricevere notifiche di caricamento della pagina, sto creando una nuova classe ObjC in Racket impostata come delegato del caricamento del frame della visualizzazione Web.

La classe simile a:

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

Quando si esegue il codice all'interno DrRacket funziona alla grande la prima volta. Ulteriori iterazioni causano il processo di morire:

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 
... 

... che sembra indicare che sia la ridefinizione della classe objC che è la causa.

C'è un modo pulito utilizzando l'FFI o più funzioni generali del racket per evitare di ridefinire la classe se già esiste?

Ho provato a eseguire il wrapping define-objc-class in modo condizionale, ma deve essere un modulo di livello superiore.

Potrei passare alle funzioni di runtime ObjC non elaborate e definire la classe delegate al volo, ma sarebbe bello evitarlo.


Solution - avvolgere il define-objc-class in un let per definire la classe in un ambito nidificato all'interno di un condizionale:

(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

sorgente completo del banco di prova: https://gist.github.com/nickmain/5136923 –

risposta

4

Non credo define-obj-class deve essere utilizzato a livello superiore. È un modulo di definizione, quindi non è possibile utilizzarlo come espressione. Si dovrebbe essere in grado di fare qualcosa di simile al seguente:

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

A proposito, sembra che una correzione per il comportamento di crash è stato commesso il 7 marzo

+0

Molte grazie - che ha funzionato! –