
Asynchronous message passing in Objective-C - steeleduncan
http://vallettaventures.com/post/15524145312/asynchronous-message-passing-in-objective-c
======
phil
These days, why not use GCD and blocks for this kind of work?

~~~
kennywinker
My thoughts exactly.

    
    
            NSOperationQueue *queue = [NSOperationQueue mainQueue];
            [queue addOperation:[NSBlockOperation blockOperationWithBlock:^{
                // do something
            }]];
    

or

    
    
            NSOperationQueue *queue = [NSOperationQueue mainQueue];
            [queue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(selectorName:) object:param1] autorelease]];
    

Edit: on re-reading the post in detail, I see the problem he is solving is
different from the one the above code solves. Clearly there is value to what
he has made. I wonder if it could not be re-coded using gcd and/or blocks, but
NSOperationQueue is too high-level an API to be appropriate.

Still, I can't tell you how many times I've used the code above to create
simple async systems.

~~~
phil
How is the problem he is solving different? I guess using an actor chain and
messages allows you to repeatedly drop many messages through the same sequence
of operations.

While you might express that slightly differently if you used GCD or operation
queues, you should be able to make it just as readable. Blocks are pretty
cheap, so any performance hit should be more than offset by the gains you get
from having the OS manage your thread pool for you.

------
richcollins
Also see ActorKit from the inventor of Io:
<https://github.com/stevedekorte/ActorKit>

------
SeanLuke
This reminds me, for some reason even though it's totally different, of NeXT's
Distributed Objects facility, which I think is still floating around OS X but
am not sure. Here's how it worked.

In Objective-C, method calls are dynamically bound. So you can make the
following call:

[myObject crazyMethodName:x:y:z]

In Java that'd be myObject.crazyMethodName(x,y,z)

However unlike Java, there doesn't have to _be_ a method called
crazyMethodName, and the compiler will still compile it just fine. What
happens is that at runtime, when this method is called, the message
"crazyMethodName" is sent to myObject. If it doesn't have a method which
responds to that name, then Objective-C calls the "forward" message on
myObject, passing in the "crazyMethodName" method name and the arguments.
"forward" can do what it likes with this -- the default implementation of
"forward" is (was?) to issue a No Such Method Found error.

What Distributed Objects did was create a special proxy object which has a
single method implemented: "forward". The system worked as follows. When
machine A connects to machine B, machine B gives machine A its "entry" object
(as defined by the user). B thinks it gave A an object, but in fact what A
received was a proxy object. Let's say that the entry object responds to a
method "foo". A calls

[obj foo]

obj is actually a proxy which responds to no methods at all, except for
"forward". Objective-C fails to call "foo" on obj, so it tries "forward", and
lo and behold the proxy has implemented that in a special way -- it wraps up
the method call and ships it over to machine B and calls "foo" on the _real_
object.

Through this procedure objects get passed as arguments back and forth through
these method calls, which in turn wind up generating more and more proxies.
Ultimately neither machine knows that the objects it's got access to are
fakes. It just feels like you've been given access to call and manipulate
another processes objects. Very clean and elegant.

~~~
krevis
No idea why this reminded you of DO -- as you say, it's a totally different
thing.

DO still works in OS X. Frankly, it's a neat hack, but it's prohibitively
difficult to build anything robust on top of it:

\- Error handling is difficult -- what happens when the other side goes down
in the middle of your method call? If you have to add extra exception and
timeout handling everywhere, that dwarfs the small convenience of making the
dispatch code easy.

\- Hard to make it secure.

\- It's impossible to interoperate with anything else -- what happens when you
want to talk to your DO-based server using Java or Windows or Linux?

See "A Note On Distributed Computing" from 1994 for more caveats on this whole
approach:

<http://labs.oracle.com/techrep/1994/abstract-29.html>

------
dgallagher
That's really cool. For the heck of it I increased the actor count to 16 and
CPU-usage stayed ~50% when running (Core i7, dual core w/hyper-threading). If
you comment out the NSLog call, it spikes to ~280% CPU usage, as the overhead
introduced by NSLog is likely slowing things down.

------
oofabz
I greatly prefer PLActorKit by Landon Fuller:
<http://code.google.com/p/plactorkit/>

------
sp00nman
Why must these sorts of contributions always be BSD licensed, what is wrong
with public domain?

~~~
aaronblohowiak
The public domain doesn't exist in some places like it does in the US. SQLlite
takes a different approach where it is all licensed under the public domain
but you can buy a license for $1,000.00

~~~
SeanLuke
The US too.

The public domain is where things go when their copyright _expires_. In most
countries -- including the United States -- there is _no legal procedure_ to
dedicate something to the public domain. You can claim something you wrote is
in the public domain until you're blue in the face, but it's not. You still
own the copyright on it.

The closest you can get to a public domain declaration is a bare license:
basically a license which says "Copyright 2012 by me: I give you the license
to do whatever you want with this." The problem with a bare license is that if
your code doesn't work right, people can (and do) turn around and sue your
pants off. Because -- remember -- the work is _not in the public domain_. You
own it and are responsible for it.

Thus we get to a BSD-style ("academic") license. At a minimum this license
says "Copyright 2012 by me: I give you a license to do whatever you want with
this as long as you agree not to sue me if something doesn't work".

Always use, at a minimum, a BSD-style license. Public domain is a fiction.

~~~
tptacek
The stridency/accuracy ratio of this comment is interesting.

<http://cr.yp.to/publicdomain.html>

~~~
dctoedt
The GP [SeanLuke] does make one good point, which is that using a BSD-style
license is a good idea, because it gives you ammunition to help defeat a
"creative" claim that you should be liable for problems other people have with
your code.

Otherwise, I agree, there are a fair number of inaccuracies in the GP
[SeanLuke] comment.

~~~
tptacek
While conceding immediately that you generally do want to take whatever "free"
steps that are available to you to avoid frivolous lawsuits, what's your take
on how likely it is that someone would prevail with a claim like "a bug in the
software code that you abandoned all claims to cost me millions of dollars"?

(I ask because I'm curious, not to further a debate about PD).

~~~
dctoedt
The odds that a plaintiff would prevail in such a claim are close to zero.
_But_ defending against the claim would cost money. "Free" steps such as the
BSD license give you a better shot at being able to stop the claim at lower
cost --- think Spock with a Vulcan neck pinch, as opposed to Kirk having to
slug it out out.

