Почему мы вызываем метод 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:
больше не будет вызываться. В принципе, это способ заставить разработчика пообещать реализовать этот метод в своем подклассе.
Кроме того, как вы упомянули, если вы не поместите это, компилятор выдает предупреждение, поскольку для метода, определенного в заголовке, не существует реализации. Это приведет к тому же поведению, что и не реализует его, но компилятор поймет, что вы делаете это специально.