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)))
전체 소스 : https://gist.github.com/nickmain/5136923 –