Почему мы вызываем метод doesNotRecognizeSelector: method?

Я работаю с сокет-программированием. Я просто хотел убрать сомнение, связанное с кодом, загруженным из - mobileorchard.com - Chatty, В то время как R & D, я видел вызов функции в файле ChatRoomViewController.m

 [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];
}

i googled для "doesNotRecognizeSelector:", в соответствии с Apple его для обработки ошибок, заявив: "Система времени выполнения вызывает этот метод всякий раз объект получает сообщение aSelector, которое он не может ответить или переадресовать". мой вопрос в том, почему разработчик вызывает функцию broadcastChatMessage: fromUser:, если ее нет в ней, и для обработки исключения метода "selector not found"?

Согласно Stackovrflow, он используется для создания абстрактного класса, в соответствии с этим , его следует избегать Предупреждение "Незавершенное исполнение".

Я до сих пор не понимаю, почему этот метод используется в Chatty Code. Просьба помочь мне понять причину использования этого метода.

Ответ 1

Это метод, который существует на каждом производном объекте NSObject, который запускает путь к исключению, когда метод не распознается во время выполнения. Например, если вы попытаетесь отправить сообщение в NSString с именем -foo, оно будет там, так как это не допустимый метод на NSString.

В этом случае класс Chatty Room является базовым классом, который никогда не используется напрямую. LocalRoom и RemoteRoom вытекают из него, и оба этих класса обеспечивают переопределяющую реализацию -broadcastChatMessage:fromUser. Никто никогда не называет эту версию базового класса, но для "полноты" программист гарантировал, что подкласс должен переопределить это, реализуя этот метод, но затем оборачиваясь и вызывая это, чтобы вызвать исключение.

Дело в том, что это не так уж идиоматично Objective-C. "Абстрактный" класс - это концепция из С++ и других языков; это базовый класс, который существует только как "шаблон", из которого в подкласс. (В ObjC это часто делается путем создания формального @protocol, когда нет значимого состояния, поскольку там (в основном) здесь нет).

Обратите внимание, что вызов -doesNotRecognizeSelector: произволен. Здесь нет необходимости избегать предупреждений компилятора (так как метод фактически реализован), и исходный писатель мог бы просто просто выбросить исключение напрямую или ничего не сделать.

Ответ 2

Мне кажется, что вы уже ответили на свой вопрос. Нет способа сделать абстрактные классы в Objective-C, поэтому самое близкое к тому, чтобы сделать это, чтобы иметь методы, которые вам нужно переопределить исключения исключения. Если вы переопределите этот метод в подклассе, то doesNotRecognizeSelector: больше не будет вызываться. В принципе, это способ заставить разработчика пообещать реализовать этот метод в своем подклассе.

Кроме того, как вы упомянули, если вы не поместите это, компилятор выдает предупреждение, поскольку для метода, определенного в заголовке, не существует реализации. Это приведет к тому же поведению, что и не реализует его, но компилятор поймет, что вы делаете это специально.