Функция, принимающая в качестве параметров протокол и экземпляр соответствующего класса (!)

Я пытаюсь выяснить, как определить функцию, которая принимает следующие два параметра:

Протокол.Экземпляручебный класс (атип ссылки) в соответствии с этим протоколом.

Например, учитывая

protocol P { }
class C : P { } // Class, conforming to P
class D { }     // Class, not conforming to P
struct E: P { } // Struct, conforming to P

это должно скомпилировать:

register(P.self, obj: C()) // (1)

но они не должны компилироваться:

register(P.self, obj: D()) // (2)  D does not conform to P
register(P.self, obj: E()) // (3)  E is not a class

Это легко, если мы отбросим условие, что второй параметр является экземпляром класса:

func register<T>(proto: T.Type, obj: T) {
    // ...
}

но это будет принимать структуру (тип значения) в(3) также. Это выглядело многообещающе и компилирует

func register<T: AnyObject>(proto: T.Type, obj: T) {
    // ...
}

но тогда ни один из(1), (2), (3) компилировать больше, например

register(P.self, obj: C()) // (1)
// error: cannot invoke 'register' with an argument list of type '(P.Protocol, obj: C)'

I предполагать что причина ошибки компилятора такая же, как вПротокол не соответствует самому себе?.

Еще одна неудачная попытка

func register<T>(proto: T.Type, obj: protocol<T, AnyObject>) { }
// error: non-protocol type 'T' cannot be used within 'protocol<...>'

Жизнеспособной альтернативой будет функция, которая принимает в качестве параметров

A учебный класс протокол.Экземпляр типа, соответствующего этому протоколу.

Здесь проблема заключается в том, как ограничить первый параметр так, чтобы были приняты только протоколы классов.

Фон: Я недавно наткнулся наSwiftNotificationCenter проект, который реализует ориентированный на протокол, механизм безопасного уведомления типа. Оно имеетregister метод, который выглядит так:

public class NotificationCenter {

    public static func register<T>(protocolType: T.Type, observer: T) {
        guard let object = observer as? AnyObject else {
            fatalError("expecting reference type but found value type: \(observer)")
        }

        // ...
    }

    // ...
}

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

Я пропускаю что-то простое / очевидное?

Ответы на вопрос(1)

Ваш ответ на вопрос