Каскадирование делегатов и «Код, который не делает то, что он говорит»

Я искал ответ на этот вопрос в документации по делегированию и протоколу Apple, но после более чем дня я решил сдаться и позволить вам, ребята, попробовать. У меня есть три класса: HTTPManager, LoginManager и FetchManager. Вы, вероятно, можете догадаться, что делают эти классы, но для ясности ...

  • HTTPManager - Обертывает NSURLConnection и предоставляет простой интерфейс для LoginManager и FetchManager для выполнения HTTP-запросов с аутентификацией.
  • LoginManager / FetchManager - в основном один и тот же класс, но они по-разному реагируют на сообщения HTTPManager.

HTTPManager ожидает, что делегат реализует протокол HTTPManagerDelegate, и это делают и LoginManager, и FetchManager. Классы Login- и FetchManager также предоставляют протокол для моего делегата приложения, чтобы данные могли возвращаться обратно в пользовательский интерфейс.

В методе init: моего делегата приложения я инициализирую как для входа в систему, так и для диспетчера выборки, и получите следующие предупреждения для обоих:

warning: class 'MyAppDelegate' does not implement the 'HTTPManagerDelegate' protocol
warning: incompatible Objective-C types assigning 'struct HTTPManager *', expected 'struct LoginManager *'

Ни один из двух инициализируемых классов не является производным от HTTPManager, но они реализуют протокол HTTPManagerDelegate. Строка кода, вызывающая указанное выше предупреждение:

_loginMgr = [[LoginManager alloc] initWithDelegate:self];

Так что же, черт возьми, делает LoginManager? s initWithDelegate: метод возвращает HTTPManager * ? Здесь нет наследования, и мои возвращаемые типы верны, так что для меня это какое-то темное вуду, которое я не умею лучше всего.

Вот оболочка моего приложения. Вероятно, есть опечатки и небольшие несоответствия, поэтому спросите меня, прежде чем предполагать синтаксическую проблему:

// HTTPManager.h

@protocol HTTPManagerDelegate
...
@end

@interface HTTPManager : NSObject
{
    id <HTTPManagerDelegate> _delegate;
    ...
}

- (HTTPManager *) initWithDelegate:(id <HTTPManagerDelegate>)delegate;
...

@end

// LoginManager.h

@protocol LoginManagerDelegate
...
@end

@interface LoginManager : NSObject <HTTPManagerDelegate>
{
    id <LoginManagerDelegate> _delegate;
    ...
}

- (LoginManager *) initWithDelegate:(id <LoginManagerDelegate>)delegate;
...

@end

// MyAppDelegate.h

@interface MyAppDelegate : NSObject <NSApplicationDelegate, LoginManagerDelegate, FetchManagerDelegate>
{
    LoginManager *_loginMgr;
    ...
}

...

@end

// MyAppDelegate.m

...

- (MyAppDelegate *) init
{
    self = [super init];

    if (self)
    {
        // WARNING HAPPENS HERE
        _loginMgr = [[LoginManager alloc] initWithDelegate:self];
        ...
    }

    return self;
}

...

Заранее спасибо.

5
задан The Maniac 8 December 2010 в 18:54
поделиться