Jump to page: 1 2
Thread overview
Dynamic binding -- Qt's Signals and Slots vs Objective-C
Sep 21, 2006
Bill Baxter
Sep 25, 2006
Fredrik Olsson
Sep 26, 2006
Bill Baxter
Sep 27, 2006
Lucas Goss
Sep 27, 2006
Fredrik Olsson
Sep 27, 2006
Lutger
Sep 27, 2006
Josh Stern
Sep 27, 2006
Lutger
Sep 27, 2006
Josh Stern
Sep 27, 2006
Lutger
Sep 27, 2006
Bill Baxter
Sep 28, 2006
Fredrik Olsson
Sep 28, 2006
d
Oct 01, 2006
Bill Baxter
Oct 02, 2006
Fredrik Olsson
Sep 26, 2006
Fredrik Olsson
September 21, 2006
There seems to be a lot in common between Qt's signals and slots (Qt S&S) and Objective-C's messaging system.  Both basically offer a way to call a method using a string rather than a pointer, i.e they allow run-time binding and dispatch.  Both seem to be considered Really Good Things by those who use them, primarily for the purpose of creating GUIs.

So is there anyone out there knowledgeable about both who could compare and contrast?  This link from Fredrik, http://tinyurl.com/kojmm, helped me understand Obj-C a little, but I've got more questions:

- Is Qt S&S a subset of Obj-C's messaging?
- Could Qt S&S be implemented using Obj-C messaging?
- Could Obj-C-like messaging be implemented using Qt S&S?
- Qt S&S includes an observer pattern in that emit() will call all connected slots.  Is this built into Obj-C messaging too?
- Qt requires derivation from QObject to participate in S&S.  Does Obj-C also require deriving from a particular base object?  Is it explicit?
- What is the overhead to support Obj-C messaging in a class?  Is there a way to create an Obj-C class that doesn't support messaging?
- Do people use Obj-C messaging for anything besides GUIs?

The goal of this questioning, of course, is to encourage discussion about whether these or any other form dynamic binding could / should be added to D.

I've heard many people in C++ land say things to the effect of "Bah, those silly Qt people weren't smart enough realize that you can implement signals and slots directly in C++".  But I've not been particularly impressed by the pure C++ S&S libraries I've seen.  On the other hand, I found Qt's S&S to be simple, clean, straightforward, and very easy to use.  And I've not heard anything but praise about making GUIs with Obj-C.  Lutger's S&S for D posted earlier looks very nice, but there must be something neat that Qt S&S--being dynamic--can do that isn't possible with the static S&S solutions.  Like enumerating available signals for use in a GUI builder tool.

- Is it possible to mix D-style classes with Obj-C style messaging?
Apple's Objective-C++ apparently doesn't allow it.
http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html
I.e. a class is either a C++ class or an Obj-C class.  They can call each other, but they are separate.  You can't send an Obj-C message to a C++ class.  I think the ideal, though, would be something closer to Qt where you have the ability to make any method you want be a slot.  In Qt those methods remain valid C++ methods, but you can also call them by name, effectively.

I think what it comes down to is that you want to have as many tools available as possible in your toolbox.  Some things are just easier to do dynamically (for flexibility and loose coupling), and other things are better done statically (for runtime speed and robust compile-time type-checking).  I think that explains the growing popularity of hybrids like Jython and JRuby.  C# probably fits in there somewhere too.

--bb
September 25, 2006
First some rech stuff :).

How Qt S&S does it:

Each object can have signals and slots. A signal is an event that can be signaled to the "runtime", and a slot is a method that is performed in response to a signal.

You connect signals and slots like this:
connect(&obj1, SIGNAL(valueChanged(int)), &obj2, SLOT(setValue(int)));
You are free to hook up a signal to as many slots as you like, and to different objects.

And you may then later emit this signal (From obj1) using:
emit valueChanged(42);
which will cause the setValue(int) slot to be performed.


How Obj-C Cocoa does it:

Each object can have an action and a target. An action is an event that is signaled at run-time, and the target is an object instance to call. If target is nil (null) then the action will be sent to the responder chain, instead of a predestined object.

The responder chain is implemented in the NSResponder protocol (Interface) and will send the action down the controllers is logical order acording to how windows are stacked, ending up in the NSApplication instance if no one else is interested. This make sure that if a single menu item (OSX == one menu you know :) ) has nil as target, then the topmost window will get a chance to respond first, and yet the same item will work for all windows.

You connect an action/target like this:
[obj1 setAction:@selector(valueChanged:)];
[obj1 setTarget:obj2];

And you can later "emit" the action using:
[obj1 sendAction:[obj1 action] to:[obj1 target]];
which will cause the valueChanged: method of obj2 to be performed. In reality most classes have shortcuts such as sendAction, and even more so you rarely need to care about sending manually at all.


Bill Baxter skrev:
<sbip>
> - Is Qt S&S a subset of Obj-C's messaging?
I think Qt's S&S is more of a superset. Qt allows a signal to trigger many slots, while Obj-C have only one target. In short, one button click invokes a single action, in Obj-C, while in Qt it could invoke a series of actions.

This is more of a design limitation in Cocoa, not in Objective-C.

On the plus-side of Cocoa is that a "signal"/"action" do not need to have a target set, but can dynamically find it's target using a responder chain, for example targetting the top-most windows document controller from a single menu item.

> - Could Qt S&S be implemented using Obj-C messaging?
Yes, no problem. And no hacks :).

> - Could Obj-C-like messaging be implemented using Qt S&S?
Yes, with some problem. The responder chain mechanism needs to be implemented.

> - Qt S&S includes an observer pattern in that emit() will call all connected slots.  Is this built into Obj-C messaging too?
As I mentioned Cocoa only use one action. So the equivalent of emit() would be performAction. But it can only be hooked up to a single target/slot.

> - Qt requires derivation from QObject to participate in S&S.  Does Obj-C also require deriving from a particular base object?  Is it explicit?
More or less. All existing senders are subclasses of NSControl, so using those subclasses will let you use say [foo sendAction], and such shorter things. In the same way subclasses of NSResponder will automatically fit in the responder chain.

But in practice, Obj-C will not care as much of the classes, but of what the classes implement. So if you send the action foo: to bar what the run-time will do is a:
if ([bar respondsToSelector:@selector(foo:)]) {
  [bar performSelector:@selector(foo:)];
}
And yes, if it does not respond, it is no error, unless you want it to be, it is perfctly legal to call methods that are not implemented :).

> - What is the overhead to support Obj-C messaging in a class?  Is there a way to create an Obj-C class that doesn't support messaging?
The Obj-C language is build upon this message dispatch, so no way around it, each "method call" is a message dispatch. And there is a overhead as compared to C++. The run-time uses caching and other neat tricks, so in practice a Obj-C method call cost about 2.5 C++ method calls.

> - Do people use Obj-C messaging for anything besides GUIs?
Oooh, yes. The real power here is in the dynamic dispatching of messages. Best of all is what is called categories. You can extend a class by subclassing, or by adding a category.

NSArray is a base class for static arrays.
NSMutableArray is a subclass of NSArray that is mutable (dynamic).
If you wanted to add a method say something useful as reversedArray to them, then in C++ (And D) you would need to make two subclasses, one to NSArray, and one to NSMutableArray, and it would be dead on impossible make a function accept both without typecasting (Ok, add an interface then). In Obj-C you can instead add a category to NSArray, and it will automatically be added to all subclasses as well. Like this:
@interface NSArray (ReversedCat)
- (NSArray *)reversedArray;
@end

And named arguments rocks, for code readability:
myFoo.write("bar.txt", true);
vs
[myFoo writeToFile:@"bar.txt" atomically:YES];

Same thing cn be done with lots of comments, but is rarely done. And short names have already become a bad habit/convention anyway.

> 
> The goal of this questioning, of course, is to encourage discussion about whether these or any other form dynamic binding could / should be added to D.
Could: YES! The first Obj-C compilers where simple preprocessors for C. I see no real problem in linking with the GNU Obj-C runtime. And Obj-C as such is very tiny, the power lies in the flexibility of the little there is.

Should: Not too sure. I would like it, my only problem with Obj-C is the C part, so replacing that with D would be nice. But I seriously doubt it is worth the trouble, mostly because it is a quite different paradigm, and before you understand it you cannot appreciate it.


> 
> I've heard many people in C++ land say things to the effect of "Bah, those silly Qt people weren't smart enough realize that you can implement signals and slots directly in C++".  But I've not been particularly impressed by the pure C++ S&S libraries I've seen.  On the other hand, I found Qt's S&S to be simple, clean, straightforward, and very easy to use.  And I've not heard anything but praise about making GUIs with Obj-C.  Lutger's S&S for D posted earlier looks very nice, but there must be something neat that Qt S&S--being dynamic--can do that isn't possible with the static S&S solutions.  Like enumerating available signals for use in a GUI builder tool.
> 
> - Is it possible to mix D-style classes with Obj-C style messaging?
> Apple's Objective-C++ apparently doesn't allow it.
> http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html
> I.e. a class is either a C++ class or an Obj-C class.  They can call each other, but they are separate.  You can't send an Obj-C message to a C++ class.  I think the ideal, though, would be something closer to Qt where you have the ability to make any method you want be a slot.  In Qt those methods remain valid C++ methods, but you can also call them by name, effectively.
> 
This is because C++/D and Obj-C works very differently. Lets call the object that will have a method called the reciever.

What C++/D does is very simply put: classes are structs with hidden function pointers, when calling a method it looks up the function pointer at a static offset from the reciever, and jumps. And the class better make sure there is a valid function at the other end.

What Obj-C does is that it takes the reciever, and requested method message and send to objc_msgSend(), that function looks up the correct function pointer for the given reciever and method pair, if found it jumps there. If not found it can raise en exception, pass control to a "unhandled message" method, or silently ignore.


Oh well, hopefully you have less question now at least :).


// Fredrik Olsson
September 26, 2006
Bill Baxter skrev:
<snip>
> - Could Qt S&S be implemented using Obj-C messaging?
Easier then I thought actually. I did it just for fun, as a category on the root class NSObject so all classes get the functionality. And it turned out to require 174 SLOC (Source Lines Of Code), and then much is convenience code that is not really needed. A minimal implementation would easily go under 100 lines of code.

The message passing is already build in, so all I did was using some existing classes to emulate the Qt behavior. One for sets to store a set of target objects. And then a hash map to store a dictionary (with the instance as key) of such sets for each instance with connected signals.

Oh well, I attach the code, and an example using it. Compiles with Xcode 2.2. Should work with with OSX 10.0 and up, and GNUStep as well.

> - Could Obj-C-like messaging be implemented using Qt S&S?
Stretching the truth one could say the the Qt S&S emitting are Obj-C like messaging, but with less optimization, only implemented for one special case, whereas Obj-C is made for the more general case. I see it as Obj-C messages with a C++ syntax.

> - Qt S&S includes an observer pattern in that emit() will call all connected slots.  Is this built into Obj-C messaging too?
No, but as can be seen in the code I attach it can very easily be emulated. Just keep the targets in a collection instance such as NSSet, NSArray or NSDictionary, and you can use makeObjectsPerformSelector: to "call all".


// Fredrik Olsson


September 26, 2006
Fredrik,
Thanks for this very informative reply.
It definitely seems from your explanations that just going for "Qt-style signals and slots" in D is "aiming low", and that a basic dynamic messaging system is more the level of abstraction you'd want.  And from there you can implement Qt-style S&S easily, as you demonstrated.

However, I think taking a 2.5x speed hit (worse for a poorly optimized implementation) for all method calls will be difficult for D users to swallow.

It sounds like basically what is required in terms of per-class storage is a second sort of vtable per class, a dynamic vtable.  Maybe more like a dictionary/hash-table, but anyway you need some place to store per-class mappings from messages to actual functions.  It could probably be pointed to from the regular vtable in some manner so that each class instance still only has the overhead of one vtable pointer.

You can go ahead and put every method in the dynamic dispatch vtable. It's just per-class, so not a huge overhead.  Kind of like how every non-private method in D is virtual.  Then I guess it needs to be the caller's choice whether to use dynamic dispatch or static.  So a separate syntax for making "message"-based calls, like Objective C uses.

Gotta go, but I think some sort of built-in dynamic dispatch mechanism like this would have to be part of my "dream language".

--bb

Fredrik Olsson wrote:
> First some rech stuff :).
> 
> How Qt S&S does it:
> 
> Each object can have signals and slots. A signal is an event that can be signaled to the "runtime", and a slot is a method that is performed in response to a signal.
> 
> You connect signals and slots like this:
> connect(&obj1, SIGNAL(valueChanged(int)), &obj2, SLOT(setValue(int)));
> You are free to hook up a signal to as many slots as you like, and to different objects.
> 
> And you may then later emit this signal (From obj1) using:
> emit valueChanged(42);
> which will cause the setValue(int) slot to be performed.
> 
> 
> How Obj-C Cocoa does it:
> 
> Each object can have an action and a target. An action is an event that is signaled at run-time, and the target is an object instance to call. If target is nil (null) then the action will be sent to the responder chain, instead of a predestined object.
> 
> The responder chain is implemented in the NSResponder protocol (Interface) and will send the action down the controllers is logical order acording to how windows are stacked, ending up in the NSApplication instance if no one else is interested. This make sure that if a single menu item (OSX == one menu you know :) ) has nil as target, then the topmost window will get a chance to respond first, and yet the same item will work for all windows.
> 
> You connect an action/target like this:
> [obj1 setAction:@selector(valueChanged:)];
> [obj1 setTarget:obj2];
> 
> And you can later "emit" the action using:
> [obj1 sendAction:[obj1 action] to:[obj1 target]];
> which will cause the valueChanged: method of obj2 to be performed. In reality most classes have shortcuts such as sendAction, and even more so you rarely need to care about sending manually at all.
> 
> 
> Bill Baxter skrev:
> <sbip>
> 
>> - Is Qt S&S a subset of Obj-C's messaging?
> 
> I think Qt's S&S is more of a superset. Qt allows a signal to trigger many slots, while Obj-C have only one target. In short, one button click invokes a single action, in Obj-C, while in Qt it could invoke a series of actions.
> 
> This is more of a design limitation in Cocoa, not in Objective-C.
> 
> On the plus-side of Cocoa is that a "signal"/"action" do not need to have a target set, but can dynamically find it's target using a responder chain, for example targetting the top-most windows document controller from a single menu item.
> 
>> - Could Qt S&S be implemented using Obj-C messaging?
> 
> Yes, no problem. And no hacks :).
> 
>> - Could Obj-C-like messaging be implemented using Qt S&S?
> 
> Yes, with some problem. The responder chain mechanism needs to be implemented.
> 
>> - Qt S&S includes an observer pattern in that emit() will call all connected slots.  Is this built into Obj-C messaging too?
> 
> As I mentioned Cocoa only use one action. So the equivalent of emit() would be performAction. But it can only be hooked up to a single target/slot.
> 
>> - Qt requires derivation from QObject to participate in S&S.  Does Obj-C also require deriving from a particular base object?  Is it explicit?
> 
> More or less. All existing senders are subclasses of NSControl, so using those subclasses will let you use say [foo sendAction], and such shorter things. In the same way subclasses of NSResponder will automatically fit in the responder chain.
> 
> But in practice, Obj-C will not care as much of the classes, but of what the classes implement. So if you send the action foo: to bar what the run-time will do is a:
> if ([bar respondsToSelector:@selector(foo:)]) {
>   [bar performSelector:@selector(foo:)];
> }
> And yes, if it does not respond, it is no error, unless you want it to be, it is perfctly legal to call methods that are not implemented :).
> 
>> - What is the overhead to support Obj-C messaging in a class?  Is there a way to create an Obj-C class that doesn't support messaging?
> 
> The Obj-C language is build upon this message dispatch, so no way around it, each "method call" is a message dispatch. And there is a overhead as compared to C++. The run-time uses caching and other neat tricks, so in practice a Obj-C method call cost about 2.5 C++ method calls.
> 
>> - Do people use Obj-C messaging for anything besides GUIs?
> 
> Oooh, yes. The real power here is in the dynamic dispatching of messages. Best of all is what is called categories. You can extend a class by subclassing, or by adding a category.
> 
> NSArray is a base class for static arrays.
> NSMutableArray is a subclass of NSArray that is mutable (dynamic).
> If you wanted to add a method say something useful as reversedArray to them, then in C++ (And D) you would need to make two subclasses, one to NSArray, and one to NSMutableArray, and it would be dead on impossible make a function accept both without typecasting (Ok, add an interface then). In Obj-C you can instead add a category to NSArray, and it will automatically be added to all subclasses as well. Like this:
> @interface NSArray (ReversedCat)
> - (NSArray *)reversedArray;
> @end
> 
> And named arguments rocks, for code readability:
> myFoo.write("bar.txt", true);
> vs
> [myFoo writeToFile:@"bar.txt" atomically:YES];
> 
> Same thing cn be done with lots of comments, but is rarely done. And short names have already become a bad habit/convention anyway.
> 
>>
>> The goal of this questioning, of course, is to encourage discussion about whether these or any other form dynamic binding could / should be added to D.
> 
> Could: YES! The first Obj-C compilers where simple preprocessors for C. I see no real problem in linking with the GNU Obj-C runtime. And Obj-C as such is very tiny, the power lies in the flexibility of the little there is.
> 
> Should: Not too sure. I would like it, my only problem with Obj-C is the C part, so replacing that with D would be nice. But I seriously doubt it is worth the trouble, mostly because it is a quite different paradigm, and before you understand it you cannot appreciate it.
> 
> 
>>
>> I've heard many people in C++ land say things to the effect of "Bah, those silly Qt people weren't smart enough realize that you can implement signals and slots directly in C++".  But I've not been particularly impressed by the pure C++ S&S libraries I've seen.  On the other hand, I found Qt's S&S to be simple, clean, straightforward, and very easy to use.  And I've not heard anything but praise about making GUIs with Obj-C.  Lutger's S&S for D posted earlier looks very nice, but there must be something neat that Qt S&S--being dynamic--can do that isn't possible with the static S&S solutions.  Like enumerating available signals for use in a GUI builder tool.
>>
>> - Is it possible to mix D-style classes with Obj-C style messaging?
>> Apple's Objective-C++ apparently doesn't allow it.
>> http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html
>> I.e. a class is either a C++ class or an Obj-C class.  They can call each other, but they are separate.  You can't send an Obj-C message to a C++ class.  I think the ideal, though, would be something closer to Qt where you have the ability to make any method you want be a slot.  In Qt those methods remain valid C++ methods, but you can also call them by name, effectively.
>>
> This is because C++/D and Obj-C works very differently. Lets call the object that will have a method called the reciever.
> 
> What C++/D does is very simply put: classes are structs with hidden function pointers, when calling a method it looks up the function pointer at a static offset from the reciever, and jumps. And the class better make sure there is a valid function at the other end.
> 
> What Obj-C does is that it takes the reciever, and requested method message and send to objc_msgSend(), that function looks up the correct function pointer for the given reciever and method pair, if found it jumps there. If not found it can raise en exception, pass control to a "unhandled message" method, or silently ignore.
> 
> 
> Oh well, hopefully you have less question now at least :).
> 
> 
> // Fredrik Olsson
September 27, 2006
Bill Baxter wrote:
> Gotta go, but I think some sort of built-in dynamic dispatch mechanism like this would have to be part of my "dream language".
> 
> --bb
> 

I think I'm of the same opinion. I'm just starting to learn Obj-C now...

lucas
September 27, 2006
Lucas Goss skrev:
> Bill Baxter wrote:
>> Gotta go, but I think some sort of built-in dynamic dispatch mechanism like this would have to be part of my "dream language".
>>
>> --bb
>>
> 
> I think I'm of the same opinion. I'm just starting to learn Obj-C now...
> 
> lucas

I want to agree as well. But hmm... how D and Obj-C tackles OOP is so very different that I can not see any way to merge the two.

So just as you can not seamlessly mix C++ classes and Obj-C classes in Objective-C++, I can not see how D classes and Obj-C classes could be mixes seamlessly in any practical way.

So if (a big IF) Obj-C type classes should ever be added to D I think an Objective-D dialect, just as Objective-C++. As a bonus there would:
1. Not be reinventing the wheel.
2. Reuse the GNU Obj-C runtime (Already optimized).
3. Reuse/link against GNUStep

I think it would be just like C<->D where code is binary compatible, and similar enough for anyone to learn. And it has already been done, with Objective Modula-2, so there is a test case to learn from.

And as I have said before; my only problem with Obj-C is C. So the thought of Objective-D appeals to me :). Garbage collection, foreach, etc. Hmm... all of which are features mentioned by Apple to be part of Objective-C 2.0 that comes next spring with OS X 10.5. But well, backward compatible can be a heavy anchor.


// Fredrik Olsson
September 27, 2006
Fredrik Olsson wrote:
<snip>
> How Obj-C Cocoa does it:
> 
> Each object can have an action and a target. An action is an event that is signaled at run-time, and the target is an object instance to call. If target is nil (null) then the action will be sent to the responder chain, instead of a predestined object.
> 
> The responder chain is implemented in the NSResponder protocol (Interface) and will send the action down the controllers is logical order acording to how windows are stacked, ending up in the NSApplication instance if no one else is interested. This make sure that if a single menu item (OSX == one menu you know :) ) has nil as target, then the topmost window will get a chance to respond first, and yet the same item will work for all windows.
> 
> You connect an action/target like this:
> [obj1 setAction:@selector(valueChanged:)];
> [obj1 setTarget:obj2];
> 
> And you can later "emit" the action using:
> [obj1 sendAction:[obj1 action] to:[obj1 target]];
> which will cause the valueChanged: method of obj2 to be performed. In reality most classes have shortcuts such as sendAction, and even more so you rarely need to care about sending manually at all.

Sounds good, but isn't it quite possible to implement this in D with a more flexible messaging system than templated S&S?

>> - Qt requires derivation from QObject to participate in S&S.  Does Obj-C also require deriving from a particular base object?  Is it explicit?
> More or less. All existing senders are subclasses of NSControl, so using those subclasses will let you use say [foo sendAction], and such shorter things. In the same way subclasses of NSResponder will automatically fit in the responder chain.
> 
> But in practice, Obj-C will not care as much of the classes, but of what the classes implement. So if you send the action foo: to bar what the run-time will do is a:
> if ([bar respondsToSelector:@selector(foo:)]) {
>   [bar performSelector:@selector(foo:)];
> }

This is also a benefit of templates, no need for a superclass and free functions, literal functions and delegates work too.

> And yes, if it does not respond, it is no error, unless you want it to be, it is perfctly legal to call methods that are not implemented :).
> 
>> - What is the overhead to support Obj-C messaging in a class?  Is there a way to create an Obj-C class that doesn't support messaging?
> The Obj-C language is build upon this message dispatch, so no way around it, each "method call" is a message dispatch. And there is a overhead as compared to C++. The run-time uses caching and other neat tricks, so in practice a Obj-C method call cost about 2.5 C++ method calls.

According to QT, templated S&S is approximately 4x the cost of a function call and QT's S&S is 10x the cost. So 2.5 certainly looks acceptably to me, but this cost is paid for all calls right? And if I understood this correctly, this also means Obj-C cannot inline member functions?

>> - Do people use Obj-C messaging for anything besides GUIs?
> Oooh, yes. The real power here is in the dynamic dispatching of messages. Best of all is what is called categories. You can extend a class by subclassing, or by adding a category.
> 
> NSArray is a base class for static arrays.
> NSMutableArray is a subclass of NSArray that is mutable (dynamic).
> If you wanted to add a method say something useful as reversedArray to them, then in C++ (And D) you would need to make two subclasses, one to NSArray, and one to NSMutableArray, and it would be dead on impossible make a function accept both without typecasting (Ok, add an interface then). In Obj-C you can instead add a category to NSArray, and it will automatically be added to all subclasses as well. Like this:
> @interface NSArray (ReversedCat)
> - (NSArray *)reversedArray;
> @end
> 

Thanks for this explanation,I'm going to look into this Objective C thing as it seems interesting.

><snip>

>> I've heard many people in C++ land say things to the effect of "Bah, those silly Qt people weren't smart enough realize that you can implement signals and slots directly in C++".  But I've not been particularly impressed by the pure C++ S&S libraries I've seen.  On the other hand, I found Qt's S&S to be simple, clean, straightforward, and very easy to use.  And I've not heard anything but praise about making GUIs with Obj-C.  Lutger's S&S for D posted earlier looks very nice, but there must be something neat that Qt S&S--being dynamic--can do that isn't possible with the static S&S solutions.  Like enumerating available signals for use in a GUI builder tool.

Yes, you could say they fulfill different purposes. This article compares them and even makes a point of using them side by side:
http://www.scottcollins.net/articles/a-deeper-look-at-signals-and-slots.html

>> - Is it possible to mix D-style classes with Obj-C style messaging?
>> Apple's Objective-C++ apparently doesn't allow it.
>> http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html
>> I.e. a class is either a C++ class or an Obj-C class.  They can call each other, but they are separate.  You can't send an Obj-C message to a C++ class.  I think the ideal, though, would be something closer to Qt where you have the ability to make any method you want be a slot.  In Qt those methods remain valid C++ methods, but you can also call them by name, effectively.
>>
> This is because C++/D and Obj-C works very differently. Lets call the object that will have a method called the reciever.
> 
> What C++/D does is very simply put: classes are structs with hidden function pointers, when calling a method it looks up the function pointer at a static offset from the reciever, and jumps. And the class better make sure there is a valid function at the other end.
> 
> What Obj-C does is that it takes the reciever, and requested method message and send to objc_msgSend(), that function looks up the correct function pointer for the given reciever and method pair, if found it jumps there. If not found it can raise en exception, pass control to a "unhandled message" method, or silently ignore.

Putting aside performance, it looks to me that the main difference is that Objective-C has good support for reflection. Maybe I'm wrong, but I'd think better reflection (wherever it comes from) support would enable to write the things you'd want to do in 'Objective-D' in D. Or not? Excuse my ignorance of Obj-C.
September 27, 2006
On Wed, 27 Sep 2006 17:55:03 +0200, Lutger wrote:

I found this comparison of different C++ approaches to signal slots with a web search.

http://slotsig.sourceforge.net/doc/features-compare.html

Can't vouch for the validity of the summary, but it might be a good starting point for further investigation.


September 27, 2006
Howdy.

Fredrik Olsson wrote:
> How Obj-C Cocoa does it:
> 
> Each object can have an action and a target. 

By this you mean each GUI widget can have an action and target, right?

> An action is an event that is signaled at run-time, and the target is an object instance to call. If target is nil (null) then the action will be sent to the responder chain, instead of a predestined object.

> The responder chain is implemented in the NSResponder protocol (Interface) and will send the action down the controllers is logical order acording to how windows are stacked, ending up in the NSApplication instance if no one else is interested. 

So it forms a kind of tree or funnel with leaves being widgets, and the root being the NSApplication instance.

> This make sure that if a single menu item (OSX == one menu you know :) ) has nil as target, then the topmost window will get a chance to respond first, and yet the same item will work for all windows.

Don't really follow you there.  Why does the topmost window get the first chance?  Just before you said it went up a chain, so it seems like the immediate container window of the item would get the first chance, and eventually the topmost window will get a chance.

Anyway, this part of your description seems much more Cocoa than Objective C.  I.e. it seems independent of the language itself, more or less just the classic "chain of responsibility" pattern.  Just something implemented on top of the messaging sys provided by Obj-C.

> You connect an action/target like this:
> [obj1 setAction:@selector(valueChanged:)];
> [obj1 setTarget:obj2];

> And you can later "emit" the action using:
> [obj1 sendAction:[obj1 action] to:[obj1 target]];
> which will cause the valueChanged: method of obj2 to be performed. In reality most classes have shortcuts such as sendAction, and even more so you rarely need to care about sending manually at all.

Ok, I'm trying to grok these message things now.
It looks like there's no distinction between method names and call parameters.  Like here:
> [obj1 setAction:@selector(valueChanged:)];
setAction looks sort of like a method with parameter being a selector. But then here:
> [obj1 sendAction:[obj1 action] to:[obj1 target]];
it looks like there are two methods, 'sendAction' and 'to'.
And I take it [obj1 action] is a named attribute lookup, similar to a QProperty?

Fredrik Olsson wrote:
> Lucas Goss skrev:
>> Bill Baxter wrote:
>>
>>> Gotta go, but I think some sort of built-in dynamic dispatch
>>> mechanism like this would have to be part of my "dream language".
>>>
>> I think I'm of the same opinion. I'm just starting to learn Obj-C now...
>
> I want to agree as well. But hmm... how D and Obj-C tackles OOP is so
> very different that I can not see any way to merge the two.

Is it really so difficult?  Maybe I just don't understand how Obj-C works well enough, but in Obj-C you have both regular C function calls (do_something(foo)) and message passing ([obj doSomething:foo]) and the user decides which paradigm to use at what time.  Similarly in an Obj-D you could have regular method calls (obj.do_something(foo)) and messaging calls ([obj doSomething:foo]).

It seems like it could work more or less the way slots do in Qt.  If I have:
# slot:
#   void callMeLater(int val);

In a Qt program, then callMeLater is a valid method that can be called like any other method.  But it is *also* callable via dynamic lookup using QObject's under-the-hood moc-generated mechanisms. I don't see why a similar idea wouldn't work for adding a touch of Obj-C to D.

> So just as you can not seamlessly mix C++ classes and Obj-C classes in
> Objective-C++, I can not see how D classes and Obj-C classes could be
> mixes seamlessly in any practical way.

Maybe I'm just not seeing the full scope of how Obj-C works yet.  But nothing I've heard so far seems like an insurmountable hurdle.

It just doesn't seem a very attractive proposition to me to have to decide at initial design time whether my class will have regular methods or use dynamic messaging.  I may know I want to start out with one or the other, but then I want my static class to recieve a particular message from a GUI.  I guess these guys at Apple have given it some thought with Obj-C++, but my initial reaction was that keeping the types of classes completely separate must be some kind of corner cutting to get the thing out the door quickly, or perhaps having something to do with preserving C++ compatibility.

--Bill
September 27, 2006
Josh Stern wrote:
> On Wed, 27 Sep 2006 17:55:03 +0200, Lutger wrote:
> 
> I found this comparison of different C++ approaches to signal slots
> with a web search.
> 
> http://slotsig.sourceforge.net/doc/features-compare.html
> 
> Can't vouch for the validity of the summary, but it might be a good
> starting point for further investigation.
> 
> 

Nice list, there are also a few benchmarks there. Depending on interpretation of course, my sigslots library scores equal points feature-wise as slotsig. There are some features in slotsig which might be worth investing, thank you for the link.
 These lists are always biased, but the biggest advantages of QT are not listed: dynamic connections which make it possible to, for example, script connections, load from xml resource, etc. This is where string based sigslots or - as I understand - Objective C is superior to the template-based implementations.
« First   ‹ Prev
1 2