ffi/unsafe/objc: fix objc-is-a? to recognize subclass instances

This repair turns out to matter for Mac OS X 10.10, where creating
a list box in a frame somehow makes the frame an instance of a
subclass (that implements notifications of some sort, I think).
That subclassing broke an `(objc-is-a? ... RacketWindow)` test to
recognize windows that belong to a particular eventspace.
This commit is contained in:
Matthew Flatt 2014-08-29 14:09:31 -06:00
parent 3a716b98c0
commit 1cb16f6c36
2 changed files with 29 additions and 3 deletions

View File

@ -258,7 +258,16 @@ Returns a selector (of FFI type @racket[_SEL]) for the string form of
@defproc[(objc-is-a? [obj _id] [cls _Class]) boolean?]{ @defproc[(objc-is-a? [obj _id] [cls _Class]) boolean?]{
Check whether @racket[obj] is an instance of the Objective-C class Check whether @racket[obj] is an instance of the Objective-C class
@racket[cls].} @racket[cls] or a subclass.
@history[#:changed "6.1.0.5" @elem{Recognize subclasses, instead of requiring an
exact class match.}]}
@defproc[(objc-subclass? [subcls _Class] [cls _Class]) boolean?]{
Check whether @racket[subcls] is @racket[cls] or a subclass.
@history[#:added "6.1.0.5"]}
@; ---------------------------------------------------------------------- @; ----------------------------------------------------------------------
@ -289,6 +298,14 @@ Registers an Objective-C class.}
Returns the class of an object (or the meta-class of a class).} Returns the class of an object (or the meta-class of a class).}
@defproc[(class_getSuperclass [cls _Class])
_Class]{
Returns the superclass of @racket[cls] or @racket[#f] if @racket[cls]
has no superclass.
@history[#:added "6.1.0.5"]}
@defproc[(class_addMethod [cls _Class] [sel _SEL] @defproc[(class_addMethod [cls _Class] [sel _SEL]
[imp procedure?] [imp procedure?]
[type ctype?] [type ctype?]

View File

@ -876,10 +876,19 @@
;; -------------------------------------------------- ;; --------------------------------------------------
(provide objc-is-a?) (provide objc-is-a?
objc-subclass?)
(define-objc class_getSuperclass (_fun _Class -> _Class))
(define (objc-is-a? v c) (define (objc-is-a? v c)
(ptr-equal? (object-get-class v) c)) (objc-subclass? (object-get-class v) c))
(define (objc-subclass? vc c)
(or (ptr-equal? vc c)
(let ([pc (class_getSuperclass vc)])
(and pc
(objc-subclass? pc c)))))
;; -------------------------------------------------- ;; --------------------------------------------------