嗨,我是Objective-C的新手,今天我正在学习动态类型和绑定的概念,直到我编写并执行了该程序后一切都很好
#import <Foundation/Foundation.h>
@interface A:NSObject
@property int var;
-(int)add:(A*)argObj;
@end
@implementation A
@synthesize var;
-(int)add:(A *)argObj
{
return (self.var + argObj.var);
}
@end
@interface B:NSObject
@property double var1;
-(double)add:(B *)argObj;
@end
@implementation B
@synthesize var1;
-(double)add:(B *)argObj
{
return (self.var1 + argObj.var1);
}
@end
int main()
{
@autorleaease{
id data1, data2;
A * aobj1 = [[A alloc]init];
aobj1.var = 30;
A * aobj2 = [[A alloc]init];
aobj2.var = 50;
data1 = aobj1;
data2 = aobj2;
NSLog(@"The sum of two A objs is : %i",[data1 add: data2]);// prints 80 which is correct
B * bobj1 = [[B alloc]init];
bobj1.var1 = 5.5;
B * bobj2 = [[B alloc]init];
bobj2.var1 = 5.5;
data1 = bobj1;
data2 = bobj2;
NSLog(@"The sum of 2 B objs is : %f",[data1 add: data2]);// prints 0.0000 why so ????
}
return 0;
}
当我在类A对象上执行add方法时,我得到了输出,但是当我在类BI上执行add方法时,得到了错误的答案。为什么是这样??
这就是我的输出的样子。在输出中,编译器会这样警告我
main.m: In function 'main':
main.m:47:5: warning: multiple methods named '-add:' found [enabled by default]
NSLog(@"The sum of two A objs is : %i",[data1 add: data2]);
^
main.m:8:1: note: using '-(int)add:(A *)argObj'
-(int)add:(A*)argObj;
^
main.m:8:1: note: also found '-(int)add:(A *)argObj'
main.m:26:1: note: also found '-(double)add:(B *)argObj'
-(double)add:(B *)argObj;
^
main.m:55:5: warning: multiple methods named '-add:' found [enabled by default]
NSLog(@"The sum of 2 B objs is : %f",[data1 add: data2]);
^
main.m:8:1: note: using '-(int)add:(A *)argObj'
-(int)add:(A*)argObj;
^
main.m:8:1: note: also found '-(int)add:(A *)argObj'
main.m:26:1: note: also found '-(double)add:(B *)argObj'
-(double)add:(B *)argObj;
^
Executing the program....
$demo
2014-01-20 04:06:05.788 demo[30357] The sum of two A objs is : 80
2014-01-20 04:06:05.789 demo[30357] The sum of 2 B objs is : 0.000000
编译器说存在多个方法,但是这些方法完全属于不同的类,而当我们使用动态类型和动态绑定时,调用将得到正确解析。那么为什么我会得到这样的输出?提前致谢.. :)
问题不是真正的关于动态绑定(按预期工作),而是关于传递参数。模糊的选择器禁止编译器知道使用哪个原型。
Objective-C使用C的ABI进行函数/方法调用和参数传递。编译器必须知道参数的类型。如果未对变量进行强类型化,则编译器将无法查找正确的选择器。如果参数不兼容(如您的情况),这将导致不确定的行为。
编辑:编译器实际上告诉您有关混乱的所有信息:
> 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'
这是在添加两个A
s时的第一次使用。编译器会通知您它使用了A类变体进行调用,这恰好是正确的。
> 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'
这是带有两个B对象的第二次日志调用。再次,编译器抱怨这两个add:
选择器存在歧义,并告知您再次选择了A变体。这次这是错误的选项,您会在运行时看到意外的结果。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句