Использование протоколов Objective C - PullRequest
15 голосов
/ 01 октября 2011

У меня вопрос по домашнему заданию, который очень смутил меня. Ниже приводится краткое объяснение вопроса.

Представьте, что вы разрабатываете приложение, которое хранит контакты Информация. Адресная книга может содержать много типов объектов, например, Человек существо, компания или что-то еще, что имеет контактную информацию.

  • Теперь вместо явной проверки каждого типа объекта напишите протокол, который объявляет, как объект должен вести себя и успешно появиться в вашей адресной книге.
<ч />

Я понимаю и стараюсь ответить на этот вопрос,

  1. Создайте протокол с общими методами для каждого типа контактной информации в теге @required. И все другие методы, которые не похожи друг на друга (например, номер факса связан с компанией, но не с лицом ...) в @optional. Во время выполнения вы можете проверить, отвечает ли объект на какой-либо данный метод, используя selector. Сомнение: Однако это опять-таки явная проверка типа объекта косвенно, я прав?

  2. Моя вторая мысль - использовать что-то вроде abstract class в Java. Это означает, что унаследованные классы от абстрактного класса реализуют свои собственные абстрактные методы. Но как наивный разработчик iOS я не знаю, как это реализовать? и я не уверен, решит ли это мою проблему. Я хотел бы получить просветление, если кто-то знает это.

<ч />

Внешнее чтение завершено. Пожалуйста, дайте мне знать, если я ищу ответ по одной из этих ссылок. Я прочитаю это снова, чтобы понять и решить это :). спасибо.

  1. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF144

  2. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF146

  3. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF149

Ответы [ 3 ]

10 голосов
/ 01 октября 2011

Протокол - это то же самое, что и интерфейс Java. Он просто определяет, какие методы класс должен поддерживать. Вот страница, которая объясняет это ясно: http://www.otierney.net/objective-c.html#protocols

По сути, если вы хотите убедиться, что класс будет иметь метод phoneNumber (доступ к свойству phoneNumber), вы должны сделать что-то вроде этого:

@protocol ContactProtocol
-(void) phoneNumber;
@end

@interface Person: NSObject <ContactProtocol> {
    ...
}

@interface Company: NSObject <ContactProtocol> {
    ...
}

А затем во время компиляции (или в реальном времени для xcode 4) он сообщит вам, если вы забыли добавить метод phoneNumber к Person или Company классам.

4 голосов
/ 01 октября 2011

Однако это опять-таки явная проверка типа объекта косвенно, я прав?

Нет, проверка поведения отличается от проверки типа.Вы можете отправить -respondsToSelector: любому объекту, и если результат ДА, вы можете отправить сообщение независимо от типа объекта.Вы также можете потребовать, чтобы объект реализовал данный протокол, опять же, не заботясь о его фактическом типе:

id<SomeProtocol> foo;  // foo points to any type that implements SomeProtocol

Моя вторая мысль - использовать что-то вроде абстрактного класса в Java.

Это может сработать, но, видимо, это не то, о чем просило ваше назначение, верно?Там написано: «... напишите протокол ...»

Objective-C не предоставляет способ явно сделать класс абстрактным, как это делает Java.Вы просто создаете класс, и если вы не хотите, чтобы он создавался напрямую, вы где-то это документируете.

1 голос
/ 01 октября 2011

У вас есть ... параметры.

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

Дополнительные методы не так плохи, как проверка типа.Представьте, как будет выглядеть код при доступе к объекту контактной сущности.Когда вы используете необязательный метод, у вас должен быть случай if и else.Это не так удобно, как просто пойти дальше и предположить, что вы можете вызвать метод.Но это намного удобнее, чем проверка типа.Это будет один случай, если для каждого другого типа объекта (и еще случай, который может быть утверждением).Кроме того, если вы используете дополнительные методы, информация о сущности инкапсулируется в ее класс.Если вы проверите тип перед вызовом метода, то информация о том, какой тип контактной информации предоставляет объект, находится вне класса в вызывающем коде.Если вы модернизируете объект, чтобы предоставить дополнительный тип контакта, это улучшение будет недоступно до тех пор, пока вы не обновите вызывающий код.

Вариант B состоит в том, чтобы сделать все необходимые методы, но дать им возможность возврата значенияэто означает, что информация недоступна, например, ноль.Конечно, это все еще означает, что в случае, если для проверки нулевого результата, это просто менее многословно.Еще лучшим решением этой проблемы является использование методов, возвращающих коллекции из нескольких контактов.В конце концов, люди могут иметь более одного номера телефона.Затем, чтобы указать, что тип контакта неприменим, вы просто вернете пустую коллекцию.

Недостатком является то, что любой, кто пишет класс, соответствующий протоколу, должен добавить простой метод-заглушку, который говорит return nilили что-то.

...