В настоящее время я ищу способы улучшить свой код. Приложение общается с сервером и получает несколько типов информации: массивы людей, массивы временных меток и т. д. Когда я начал писать код, который взаимодействует с сервером, я создал базовый класс WebService, который настраивает AFNetworking (URL, менеджер и т. д.) и имеет делегат, вызываемый в блоках.
Каждый раз, когда мне нужен был новый сервис, я создавал новый класс, наследуемый от этого класса. Каждый класс объявляет свой собственный протокол для делегата для получения данных. Около 90% методов протокола в этих классах помечены как обязательные, потому что я хочу убедиться, что делегат может получать данные.
На данный момент я занимаюсь рефакторингом кода и заметил, что около половины моих протоколов делегатов требуют «успешного» метода и «неудачного» метода. Я решил, что все функции, которым просто нужны эти два метода, должны быть реализованы в родительском классе, чтобы иметь меньше протоколов для соответствия в моих контроллерах представления. Я начал процесс, но когда я меняю объявление своего делегата с id delegate
на id<WebServiceDelegate> delegate
, все дочерние классы ожидают, что их делегат будет соответствовать протоколу WebServiceDelegate, и я получаю ошибки компиляции.
Моя цель состоит в том, чтобы иметь дочерние классы только для соединений, которым НЕ нужен метод успеха и неудачи, поэтому я не хочу просто расширять протокол. Наследование от NSObject вместо WebService также кажется расточительным, поскольку мне приходится снова настраивать AFNetworking во всех них (повторяющийся код).
На данный момент я не заставляю делегата соответствовать какому-либо протоколу, но я хотел бы обеспечить это. Мое единственное разумное решение — добавить еще одного делегата в дочерние классы, который соответствует только протоколу дочернего класса, но я чувствую, что должен быть лучший.
Таким образом, мой вопрос: как мне заставить делегата дочернего класса соответствовать новому протоколу вместо родительского протокола?
Пример текущего кода:
// Parent Class
@interface WebService : NSObject
@property (weak) id delegate;
// Child Class
// there's a few child class protocols that just implement this 2 methods
@protocol UploadServiceDelegate <NSObject>
@required
- (void) uploadServiceSuccess;
- (void) uploadServiceFailure;
@end
@interface UploadService : WebService
// Here is a more complicated protocol
@protocol ScheduleServiceDelegate <NSObject>
@required
- (void) scheduleServiceSuccess;
- (void) scheduleServiceFailure;
@optional
- (void) receiveSchedule: (NSArray*)schedules;
- (void) receiveURLForCertificate: (NSURL*) certURL;
@end
Пример идеального кода, в этом случае все объявления протоколов *Success и *Failure больше не нужны, поскольку методы, которые их вызывают, будут реализованы в родительском классе:
@protocol WebServiceDelegate <NSObject>
@required
- (void) WebServiceSuccess;
- (void) WebServiceFailure;
@end
@interface DGWebService : NSObject
@property (weak) id<WebServiceDelegate> delegate;
Таким образом, другие протоколы будут объявлять только те методы, которые необходимы, и делать их @required
вместо необязательных. Это тот момент, когда я думаю, что мне нужно новое объявление свойства делегата:
@protocol ScheduleServiceDelegate <NSObject>
@required
- (void) receiveSchedule: (NSArray*)schedules;
- (void) receiveURLForCertificate: (NSURL*) certURL;
@end
// Delegate at this point:
@property (weak) id<WebServiceDelegate> delegate;
// Delegate I need:
@property (weak) id<ScheduleServiceDelegate> delegate;
id<ScheduleServiceDelegate>
? Таким образом, делегату нужно только соответствоватьScheduleServiceDelegate
, чего вы и хотите? 05.12.2014@property (weak) id<ScheduleServiceDelegate> delegate;
в моем дочернем классе даст такое поведение? 05.12.2014respondsToSelector
, все должно быть в порядке! 05.12.2014Property type 'id'<OtherDelegate> is incompatible with the type 'id<WebServiceDelegate>' inherited from 'WebService'
Я предполагаю, что с предупреждениями все в порядке, но я бы предпочел их избегать. 05.12.2014