为什么我们要调用doesNotRecognizeSelector:方法?

问题描述:

我正在使用套接字编程。我只是想清除与我从 - mobileorchard.com - Chatty下载的代码有关的疑问。虽然ř& d,我看到一个函数调用在ChatRoomViewController.m文件为什么我们要调用doesNotRecognizeSelector:方法?

[chatRoom broadcastChatMessage:input.text fromUser:[AppConfig getInstance].name]; 

当我在Room.m文件看到,对于上述呼叫的执行;它是

- (void)broadcastChatMessage:(NSString*)message fromUser:(NSString*)name 
{ 
    // Crude way to emulate an "abstract" class 
    [self doesNotRecognizeSelector:_cmd]; 
} 

我GOOGLE为“doesNotRecognizeSelector:”,根据其Apple用于错误处理,说明“运行时系统调用只要对象接收aSelector消息时,它不能响应或转发该方法”我的问题是,为什么开发者调用broadcastChatMessage:fromUser:函数,如果它没有在那里使用,并且处理哪个方法的“selector not found”异常?

根据Stackovrflow,其用于创建抽象类,根据此Question,其避免“不完整的实现”警告。

我仍然不明白为什么该方法用于那个Chatty Code,请帮助我理解为什么使用该方法的原因。

+1

看起来好像该应用程序的原始开发人员正试图模拟C++抽象基类的功能,因为它的实例无效。它只是一种更极端的形式,使方法无所作为或返回占位符值(通常为0或NULL)。 – CodaFi 2013-04-09 05:43:15

这是存在于每个NSObject派生对象上的方法,该方法在运行时调用中未识别某个方法时会触发发生异常的路径。例如,如果您尝试向NSString发送邮件-foo,它将最终结束,因为这不是NSString上的有效方法。

在这种情况下,Chatty类Room是从不直接使用的基类。 LocalRoomRemoteRoom派生自它,并且这两个类都提供了-broadcastChatMessage:fromUser的重要实现。没有人曾经调用过这个基类的版本,但是对于“完整性”,程序员已经保证了子程序员必须通过实现这个方法来覆盖它,但是然后转过身来调用它来触发异常。

事情是,这不是特别惯用的Objective-C。 “抽象”类是C++和其他语言的概念;它的基类只是作为子类的“模式”存在。 (在ObjC中,这通常通过在没有意义的状态时创建正式的@protocol来完成,因为那里(大部分)不在这里)。

请注意,致电-doesNotRecognizeSelector:是任意的。在这里没有必要避免编译器警告(因为方法实际上已经实现),并且原作者可能很容易直接抛出异常,或者什么都不做。

在我看来,你已经回答了你自己的问题。没有办法在Objective-C中创建抽象类,所以最接近的做法是让你需要重写抛出异常的方法。如果在子类中重写此方法,则不再调用doesNotRecognizeSelector:。基本上这是一种让开发人员承诺在其子类中实现此方法的方法。另外,正如你所提到的,如果你不把它放进去,那么编译器会发出一个警告,因为在头文件中定义的方法没有实现。这将执行与不执行相同的行为,但编译器会意识到您正在故意这样做。