2016-03-02 1 views
6

Я хочу написать протокол со слабым требованием к свойствам. Соответствующий класс должен иметь возможность указать любой тип этого свойства. Также я не хочу указывать фактический тип, поэтому он должен быть типом, указанным с некоторым протоколом. Этот код показывает мою идею для слабого свойства:Незначительные требования к свойствам в протоколе Swift со связанным типом

protocol ObjectProtocol: class { 
    typealias PropertyType 
    var property: PropertyType {get set} 
} 

protocol FirstPropertyProtocol: class {} 
protocol SecondPropertyProtocol: class {} 

class FirstObjectImpl: ObjectProtocol { 
    var property: FirstPropertyProtocol? 
} 

class SecondObjectImpl: ObjectProtocol { 
    var property: SecondPropertyProtocol? 
} 

Работает так, как ожидалось.

Я попытался сделать то же самое для слабой собственности:

protocol ObjectProtocol: class { 
    typealias WeakPropertyType: AnyObject //must be a class type 
    weak var weakProperty: WeakPropertyType? {get set} 
} 

protocol WeakPropertyProtocol: class {} 

class ObjectImpl: ObjectProtocol { 
    weak var weakProperty: WeakPropertyProtocol? 
} 

И я получил ошибку компилятора:

Type 'ObjectImpl' does not conform to protocol 'ObjectProtocol'

Есть ли способ, что я могу сделать эту работу?

+0

Проблема заключается в том, что протокол не соответствует самому по себе, а не к любому протоколу, что он наследует от, см http://stackoverflow.com/questions/33112559/protocol -doesnt-соответствовать самому себе для аналогичной проблемы. В вашем случае тип WeakPropertyProtocol does * not * соответствует AnyObject. –

+0

Спасибо, комментарий, Мартин. Есть ли другой способ указать, что мой 'WeakPropertyType' является типом класса без этого ограничения AnyObject? –

+0

Протоколы в настоящее время не могут требовать, чтобы свойства были реализованы как слабые хранимые свойства. https://stackoverflow.com/questions/47699813/weak-property-in-a-swift-protocol – Adobels

ответ

3

Я не верю, что протокол может обеспечить слабость. Например:

protocol ObjectProtocol: class { 
    weak var weakProperty: AnyObject? {get set} 
} 

class ObjectImpl1: ObjectProtocol { 
    weak var weakProperty: AnyObject? 
} 

class ObjectImpl2: ObjectProtocol { 
    var weakProperty: AnyObject? 
} 

Эти и компилировать в порядке, даже если протокол имеет weak но ObjectImpl2 не реализует его.

EDIT: Это то, что вы после ...

protocol ObjectProtocol: class { 
    typealias WeakPropertyType: Any //must be a class type 
    var weakProperty: WeakPropertyType? {get set} 
} 

protocol WeakPropertyProtocol: class {} 

class ObjectImpl: ObjectProtocol { 
    typealias WeakPropertyType = WeakPropertyProtocol 
    weak var weakProperty: WeakPropertyProtocol? 
} 

Эта реализация требует использования каких-либо, а не AnyObject, поскольку WeakPropertyProtocol представляет собой протокол, а не класс?.

Или это? ...

protocol WeakPropertyProtocol: class {} 

protocol ObjectProtocol: class { 
    typealias WeakPropertyType: AnyObject //must be a class type 
    var weakProperty: WeakPropertyType? {get set} 
} 

class MyWeakClass: WeakPropertyProtocol { 

} 

class ObjectImpl: ObjectProtocol { 
    typealias WeakPropertyType = MyWeakClass 
    weak var weakProperty: MyWeakClass? 
} 

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

+0

Это интересно, но я не могу принять ваш ответ. Мне не нужно принуждать к слабости. Но мне нужно объявить это свойство слабым в классе, которое соответствует моему протоколу.Только свойство с типом класса может быть слабым, и я не могу найти, как указать это без ограничения 'AnyObject'. –

+0

Я неправильно понял ваш вопрос. Я уточню свой ответ. – Michael

+0

Спасибо, Майкл! Второй - это то, что мне нужно. Он работает хорошо, но я обеспокоен тем, что 'weakProperty' в' ObjectProtocol' не указан с помощью ссылки «слабый». Также мне нужно явно указать тип для псевдонима 'WeakPropertyType' в реализации класса. В любом случае, ваше решение лучше для меня в данный момент. –

2

Я сделал это работать с @objc атрибутом для WeakPropertyProtocol:

protocol ObjectProtocol: class { 
    typealias WeakPropertyType: AnyObject //must be a class type 
    weak var weakProperty: WeakPropertyType? {get set} 
} 

@objc protocol WeakPropertyProtocol {} 

class SomeObjectImpl: ObjectProtocol { 
    weak var weakProperty: WeakPropertyProtocol? 
} 

Это не лучшее решение, потому что я отношусь об этой записке от apple doc

Note also that @objc protocols can be adopted only by classes that inherit from Objective-C classes or other @objc classes.

Я могу жить с этим ограничением, но я оценят любое лучшее решение.

0

Swift 4 версия.
Мне были нужны мои модели просмотра для соответствия протоколу. Они не должны сохранить координатор объекта:

protocol ViewModelType { 
    associatedtype CoordinatorType: AnyObject 
    weak var coordinator: CoordinatorType? { get } 
} 
+1

Протоколы в настоящее время не могут требовать, чтобы свойства были реализованы как слабые хранимые свойства. https://stackoverflow.com/questions/47699813/weak-property-in-a-swift-protocol – Adobels

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