2012-08-02 62 views
0

这是轻微的从先前的问题遵循:回应,但不知道?

for(id <stuffieProtocol> eachObject in stuffieArray) { 
    if([eachObject respondsToSelector:@selector(secretID)]) [eachObject secretID]; 
} 

以上是从快速枚举循环的线,需要一个数字对象的出NSArray和检查,以查看它们是否该方法响应secretID。方法secretID不是@protocol的一部分,而是在集合中的一个对象上定义的方法。

因为编译器说"No known instance method for selector secretID"这很好,id不关心和方法不<stuffieProtocol>定义我可以通过铸造每个对象的类型,它定义了解决这个问题的if上述声明失败secretID:

if([eachObject respondsToSelector:@selector(secretID)]) [(Ted *)eachObject secretID]; 

我的问题是在原代码,编译器如何知道eachObject响应的方法secretID,但尚未当你问它来调用该方法的说:“没有已知的方法,”我只是有点好奇的机制?

+0

铸造成'特德*'让我不安 - 我宁愿投给'id',否则你是隐式记录,如果对象响应'secretID'则是必须Ted'的'一个实例,这可能并不总是成立,你可能只是试图通过撒谎来使编译器沉默。只要编译器能够看到声明该方法的头文件,就可以转换为'id'。你已经导入了一个类来声明一个方法'secretID'就像你的'Ted'类。 – 2012-08-02 15:06:09

回答

2

编译器不知道对象是否响应该选择器,但运行时确实如此。 (即编译器不执行代码)。编译器只关心任何NSObject都可以响应respondsToSelector:

+0

我看到,添加(Ted *)只是告诉编译器“secretID”在哪里实现,respondsToSelector:直到运行时才会起作用。 – fuzzygoat 2012-08-02 13:48:54