2013-03-11 5 views
6

Ich verwende das Racket Objective-C FFI, um ein WebKit WebView in eine App einzubetten.Racket Objective-C FFI - Erneute Definition einer Klasse vermeiden

Um Benachrichtigungen über den Seitenladevorgang zu erhalten, erstelle ich eine neue ObjC-Klasse in Racket, die als Frameload-Delegat der Webansicht festgelegt ist.

Die Klasse sieht ungefähr so ​​aus:

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

Wenn der Code ausgeführt wird innerhalb DrRacket es toll das erste Mal funktioniert. Weitere Iterationen bewirken, dass der Prozess sterben:

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

... das scheint darauf hinzudeuten, dass es die Neudefinition der ObjC Klasse ist, die die Ursache ist.

Gibt es einen sauberen Weg mit den FFI, oder allgemeinere Racket-Funktionen, um zu vermeiden, die Klasse neu zu definieren, wenn sie bereits existiert?

Ich habe versucht, define-objc-class in einem bedingten, aber es muss ein Top-Level-Formular sein.

Ich könnte zu den rohen ObjC-Laufzeitfunktionen und definieren Sie die Delegate-Klasse im laufenden Betrieb - aber es wäre schön, das zu vermeiden.


Lösung - wickeln Sie die define-objc-class in einem let die Klasse in einem verschachtelten Bereich innerhalb eines bedingten zu definieren:

(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

Volle Quelle des Testbed: https://gist.github.com/nickmain/5136923 –

Antwort

4

Ich glaube nicht, define-obj-class auf höchster Ebene verwendet werden muss. Es ist jedoch ein Definitionsformular, daher können Sie es nicht als Ausdruck verwenden. Sie sollten so etwas wie die folgenden zu tun in der Lage: BTW

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

, es wie ein Update für das Krachen Verhalten sieht am 7. März begangen wurde

+0

Vielen dank - das hat funktioniert! –

Verwandte Themen