具有关联类型的Swift协议中的弱属性要求

时间:2023-01-24 00:02:27

I want to write a protocol with weak property requirement. Class that conforms it must be able to specify any type for this property. Also I don't want to specify an actual type, so it should be a type specified with some protocol. This code shows my idea for non-weak property:

我想写一个具有弱属性要求的协议。符合它的类必须能够为此属性指定任何类型。此外,我不想指定实际类型,因此它应该是使用某些协议指定的类型。此代码显示了我对非弱属性的想法:

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?
}

It works as expected.

它按预期工作。

I tried to do the same for weak property:

我试图为弱财产做同样的事情:

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?
}

And I got a compiler error:

我收到了一个编译器错误:

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

类型'ObjectImpl'不符合协议'ObjectProtocol'

Is there any way I can make this work?

我有什么方法可以做这个工作吗?

3 个解决方案

#1


4  

I don't believe a protocol can enforce weak-ness. For example:

我不相信协议可以强制执行弱点。例如:

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

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

class ObjectImpl2: ObjectProtocol {
  var weakProperty: AnyObject?
}

These both compile ok, even though the protocol has weak but ObjectImpl2 does not implement it.

这些都编译正常,即使协议有弱但ObjectImpl2没有实现它。

EDIT: Is this what you're after?...

编辑:这是你想要的吗?...

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?
}

This implementation requires use of Any rather than AnyObject, since WeakPropertyProtocol is a protocol rather than a class.

此实现需要使用Any而不是AnyObject,因为WeakPropertyProtocol是一个协议而不是一个类。

Or this?...

或这个?...

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?
}

Either way, I think the key is in defining which class/protocol to use for WeakPropertyType.

无论哪种方式,我认为关键在于定义用于WeakPropertyType的类/协议。

#2


3  

I made it work with @objc attribute for WeakPropertyProtocol:

我使用WeakPropertyProtocol的@objc属性:

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?
}

It's not a best solution because I concern about this note from apple doc

这不是最好的解决方案,因为我关注苹果doc的这个说明

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

另请注意,@ objc协议只能由继承自Objective-C类或其他@objc类的类采用。

I can live with this restriction but I will appreciate any better solution.

我可以忍受这个限制,但我会感谢任何更好的解决方案。

#3


0  

Swift 4 version.
I needed my view models to conform to a protocol. They mustn't retain a coordinator object:

Swift 4版。我需要我的视图模型符合协议。他们不能保留协调器对象:

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

#1


4  

I don't believe a protocol can enforce weak-ness. For example:

我不相信协议可以强制执行弱点。例如:

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

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

class ObjectImpl2: ObjectProtocol {
  var weakProperty: AnyObject?
}

These both compile ok, even though the protocol has weak but ObjectImpl2 does not implement it.

这些都编译正常,即使协议有弱但ObjectImpl2没有实现它。

EDIT: Is this what you're after?...

编辑:这是你想要的吗?...

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?
}

This implementation requires use of Any rather than AnyObject, since WeakPropertyProtocol is a protocol rather than a class.

此实现需要使用Any而不是AnyObject,因为WeakPropertyProtocol是一个协议而不是一个类。

Or this?...

或这个?...

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?
}

Either way, I think the key is in defining which class/protocol to use for WeakPropertyType.

无论哪种方式,我认为关键在于定义用于WeakPropertyType的类/协议。

#2


3  

I made it work with @objc attribute for WeakPropertyProtocol:

我使用WeakPropertyProtocol的@objc属性:

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?
}

It's not a best solution because I concern about this note from apple doc

这不是最好的解决方案,因为我关注苹果doc的这个说明

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

另请注意,@ objc协议只能由继承自Objective-C类或其他@objc类的类采用。

I can live with this restriction but I will appreciate any better solution.

我可以忍受这个限制,但我会感谢任何更好的解决方案。

#3


0  

Swift 4 version.
I needed my view models to conform to a protocol. They mustn't retain a coordinator object:

Swift 4版。我需要我的视图模型符合协议。他们不能保留协调器对象:

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