djdrzzy; they are, in fact, the same; unless your talking about changing the state of an action while it runs from code, which is different from anything I've seen people talking about in this conversation.
If you simply want to construct an action from, say, a text-based plist file, NSCoding works just fine for that. That's because NSDictionary (or NSData) is both NSCoding compliant and can be passed to a static function on NSKeyedArchiver to construct an object; like so:
// construct with an NSDictionary from a plist
// first create an NSDictionary object and fill it out with the plist
NSDictionary * mydata = [NSDictionary initWithContentsOfFile:@"myfile.plist"];
Action* a = [NSKeyedUnarchiver unarchiveObjectWithData:[mydata objectForKey:@"myaction"]];
This was typed from memory, so don't expect it to compile. But basically you can define a bunch of actions in a plist, then construct them from that data regardless of what type of action it is, or what properties/variables it has (since we're using the base class). This is exactly what several people have asked for in this thread, and has many advantages over any of the other proposed solutions.
Also, some of the proposed solutions just don't make sense to me. For instance, stripping the init methods of the required parameters which make an action useful not only makes them harder to use, but prevents the kind of in-line sequencing that's cool about actions. I also have to know their internal structure before I can really use them, because the init method will not produce anything meaningful on it's own. That's always a bad design, IMO, in that good API's make it easy for you to construct and use objects without knowing how they work. For instance, if we remove the arguments from the constructors:
// construct a sequence of actions in one go using arguments
id seq = [Sequence actions:[MoveTo actionWithDuration:0.5 position:ccp(0,0)], [MoveTo actionWithDuration:0.5 position:ccp(100,100)], nil];
// in a no argument world, this becomes a lot more to write
id action1 = [[[MoveTo alloc] init] autorelease];
id action2 = [[[MoveTo alloc] init] autorelease];
action1.position = ccp(0,0);
action2.position = ccp(100,100);
action1.duration = 0.5;
action2.duration = 0.5;
id seq = [[[Sequence alloc] init] autorelease];
NSMutableArray* list = [NSMutableArray array];
seq.actions = list;
And if I only have the dictionary constructor it gets even worse.
In addition, NSCoding support gives us a ton more flexibility. For instance, you could save or load the entire sequence from a file as a single entity because NSCoding stores the object graph as well (in the non-plist cases). You could also store it mid-execution, and have it pick up right where it left off when you un-pause the game. We also get tools for handling versioning of objects, so if formats or data change it can load old versions and convert them into the new versions on save.