2013-03-11 2 views
6

Racket Objective-C FFI를 사용하여 WebKit WebView를 앱에 임베드했습니다.Rape Objective-C FFI - 클래스 재정의 방지

페이지로드 알림을 받으려면 웹보기의 프레임로드 위임자로 설정된 새로운 ObjC 클래스를 라켓에 생성합니다. 이 좋은 처음 작동 DrRacket 내에서 코드를 실행하는 경우

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

:

클래스는 같이 보입니다. 그것이 원인이되는 ObjC 클래스의 재 정의임을 나타내는 것

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

을 ... : 또한 반복 프로세스가 죽는 원인이된다.

이미 존재하는 경우 클래스를 다시 정의하지 않으려면 FFI 또는보다 일반적인 라켓 기능을 사용하여 깨끗한 방법이 있습니까?

define-objc-class을 조건부로 배치했지만 최상위 형식이어야합니다.

원시 ObjC 런타임 함수로 드롭 다운하고 즉석에서 델리게이트 클래스를 정의 할 수는 있지만이를 피하는 것이 좋습니다.


솔루션 - 조건부 안에 중첩 된 범위에서 클래스를 정의 할 let에서 define-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 –

답변

4

내가 define-obj-class가 최상위 수준에 사용해야합니다 생각하지 않습니다. 하지만 정의형이므로 표현식으로 사용할 수 없습니다. 다음과 같은 것을 할 수 있어야한다 :

: 그것은

+0

많은 감사 - 일했다! –

1

월 7에 최선을 다하고 된 충돌 행동에 대한 수정처럼 보이는, BTW

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

을 그냥 경우에 당신은 그것을 놓쳤다 https://github.com/shekari/racket-webkit/blob/master/webkit.rkt

즐길 수, 테스트 베드의

+0

정말 유용하게 보입니다 - 많은 감사합니다! –