I’ve created an NSScrollView subclass like so, overriding the tile() method…
dim MyScrollViewClass As Ptr
MyScrollViewClass = objc_allocateClassPair(NSClassFromString("NSScrollView"), "MyScrollViewClass", 0)
objc_registerClassPair(MyScrollViewClass)
if not class_addMethod(MyScrollViewClass, NSSelectorFromString("tile"), AddressOf impl_tile, "v@:") then break
Shared Sub impl_tile(id As Ptr, sel As Ptr)
//call [super tile];
End Sub
How would I do the equivalent of “[super tile];” in the implementation?
[code]Structure objc_super
receiver As Ptr
pClass As Ptr
End Structure
Declare Function object_getClass Lib “libobjc.A.dylib” (id As Ptr) As Ptr
Declare Function class_getSuperclass Lib “libobjc.A.dylib” (cls As Ptr) As Ptr
Declare Function sel_registerName Lib “libobjc.A.dylib” (str As CString) As Ptr
Declare Sub objc_msgSendSuper Lib “libobjc.A.dylib” (sup As objc_super, op As Ptr) As Ptr
Dim sup As objc_super
sup.receiver = NSScrollViewInstancePtr
sup.pClass = class_getSuperclass(object_getClass(NSScrollViewInstancePtr))
Thanks Eli, this is exactly what I needed. Had to make a few changes to get it working, the objc_msgSendSuper signature is…
id objc_msgSendSuper(struct objc_super *super, SEL op, …)
I’m not sure about the return type, the declare works both as a Function or Sub. The trick was the objc_super parameter is a pointer and passing a Structure was always crashing, changing this to a Memoryblock got it working. Thanks again, this has opened up a whole new world.
[code]Private Shared Sub impl_tile(id As Ptr, sel As Ptr)
Declare Function object_getClass Lib “libobjc.A.dylib” (id As Ptr) As Ptr
Declare Function class_getSuperclass Lib “libobjc.A.dylib” (cls As Ptr) As Ptr
Declare Sub objc_msgSendSuper Lib “libobjc.A.dylib” (sup As Ptr, op As Ptr)
dim mem As new MemoryBlock(8)
mem.Ptr(0) = id
mem.Ptr(4) = class_getSuperclass(object_getClass(id))
It would have to be a ByRef parameter if it was a structure.
You should be using objc_getClass with a hardcoded class name instead of class_getSuperclass because class_getSuperclass only returns the immediate super. If something were to subclass your class, which can happen, you’ll end up with infinite recursion.
One other thing to note is that when you’re sending messages directly and not through the compiler’s Obj-C declare mechanism, you need to know what objc_msgSend variant to use. Greg Parker had a fairly good writeup of which to use in a mailing list reply from 2008 called ‘Re: Returning values from objc_msgSend etc’. It doesn’t mention any of the super variants, but the rules are similar.
Thanks Joe, I just ran into this. Had NSScroller.drawKnob overridden and calling it’s immediate super and got a StackOverflow when unplugging my mouse. Not sure how the classes change like that, there’s a whole lot to learn
[code]Private Shared Sub impl_tile(id As Ptr, sel As Ptr)
const Cocoa = “Cocoa”
declare function NSClassFromString lib Cocoa (aClassName as CFStringRef) as Ptr
declare sub objc_msgSendSuper lib Cocoa (byref sup As objc_super, op As Ptr)
dim sup As objc_super
sup.receiver = id
sup.pClass = NSClassFromString(“NSScrollView”)
objc_msgSendSuper(sup, sel)
//further repositioning…
End Sub
Structure objc_super
receiver As Ptr
pClass As Ptr
End Structure[/code]