2015-08-07 1 views
0

Проблема: объект модели определен в структуре, протокол определен в целевой программе. Цель приложения - знание структуры, но не наоборот, поэтому соответствие протокола не может быть в объявлении объекта модели.Быстрое расширение для соответствия протокола по объекту в каркасе вызывает бесконечный цикл

Однако объект модели уже имеет большинство полей, необходимых для выполнения протокола (в основном объявления var {get}), и - это, по-видимому, те же те же имена. В реальной модели имеется около 20 свойств.

Неудивительно, что следующий шаблон производит бесконечный цикл:

//Framework Target: 

public struct Book { 
    public let numberOfPages : Int 
} 

.

//App target: 

public protocol BookViewDataSource { 
    var numberOfPages : Int { get } 
} 

extension Book : BookViewDataSource { 
    public var numberOfPages : Int { return self.numberOfPages } 
} 

Но какова альтернатива? Отклоненные/неудачные идеи:

  1. View принимает модель напрямую. Обычный подход, всегда плохой, потому что он плотно соединяет представление и модель. Использование интерфейса на основе протокола позволяет легко переключаться с макетными объектами во время разработки и во время выполнения.
  2. Различные имена. Придавая свойствам протокола и свойствам структуры, разные имена будут работать, но загромождают именование и глупо, потому что все дело в том, что объект модели имеет почти точно данные, необходимые для представления. Мы поддерживаем его в рамках (после рекомендации WWDC 14 «Построение современных рамок»), чтобы обеспечить лучшее повторное использование в расширении share.
  3. Модель знает о протоколе. Теперь мы принимаем протоколы, написанные для просмотров, чтобы определить нужные им данные и переместив их в рамки. Смешно, но совершенно исключает необходимость расширения.
  4. Расширения протокола. Если мы сможем определить стандартную реализацию протокола, который ссылается на себя, то объекты, которые выполняют протокол, будут просто получать доступ к их геттерам? Но в то время как нет встроенной ошибки, компилятор (конкретный компоновщик) не допустит этого, ссылаясь на «свидетель протокола», настаивая на том, что книга все еще не выполняет протокол (мы сохраняем расширение для вычисления свойств, которых у него нет) ,

Все это выглядит как общий сценарий, просто чтобы указать, что тип уже выполняет протокол. Не хватает ли мы какого-либо простого способа сделать это, или есть причина, почему/как мы должны выбирать вышеуказанный подход? Спасибо.

+0

В декларации 'Расширение книги: BookViewDataSource', просто оставьте строку реализации, компилятор все еще вычисляет ее. – GoatInTheMachine

+0

@GoatInTheMachine говорит: «Расширения не могут содержать сохраненные свойства» –

ответ

1

Это работает для меня, выходя из декларации реализации компилятор все еще в состоянии выяснить соответствие Book,:

public struct Book { 
    public let numberOfPages : Int 
} 

public protocol BookViewDataSource { 
    var numberOfPages : Int { get } 
} 

extension Book : BookViewDataSource { 
} 

let x = Book(numberOfPages: 3) 
print(x) 

Вышеперечисленные работы по SwiftStub, я не могу получить на Mac в данный момент!

+1

Это работает - если объект находится в одной и той же цели. Не работает, если объект находится в рамках. Может прийти к неадекватности компоновщика. –

+0

Работает с Xcode 8, даже если объект находится в рамках – Dale

0

Компилятор должен понять это для вас, если вы не выполняете реализацию в расширении. Поэтому это следует рассматривать как ошибку (ошибку компоновщика).

Вы обновили до Xcode 7 beta 5? Поскольку эта версия разрешает некоторые из них.

Смежные вопросы