The problem is not really about dynamic binding (which works as expected) but about passing the parameters. Ambiguous selectors prohibit that the compiler knows which prototype to use.
Objective-C uses C's ABI for function/method calling and argument passing. The compiler has to know the types of the arguments. If an variable is not strongly typed the compiler can not look up the correct selector. If the parameters are not compatible (as in your case) this will lead to undefined behavior.
Edit: The compiler actually tells you all about the confusion:
> main.m:47:5: warning: multiple methods named '-add:' found
> NSLog(@"The sum of two A objs is : %i",[data1 add: data2]);
> [...] note: using '-(int)add:(A *)argObj'
This is for the first use when adding two A
s. The compiler informs you that it used the class A variant for the call which is, by coincidence, correct.
> main.m:55:5: warning: multiple methods named '-add:' found
> NSLog(@"The sum of 2 B objs is : %f",[data1 add: data2]);
> [...] note: using '-(int)add:(A *)argObj'
That's the second log call with two B objects. Again the compiler complains that there's the ambiguity with the two add:
selectors and informs you that it, again, chose the A variant. This time that's the wrong option and you see the unexpected results during runtime.