Swift 重新实现协议扩展中添加的函数isn’;我没打电话
我为一个协议添加了一个协议扩展,该协议的关联类型为Swift 重新实现协议扩展中添加的函数isn’;我没打电话,swift,Swift,我为一个协议添加了一个协议扩展,该协议的关联类型为PickerType。我编写了一个函数的重新实现,refresh(:,completion:),该函数在协议中定义,并在不同的协议扩展中实现 但是当我调用refresh(:,completion:)时,不会调用新扩展中的函数,除非编译器知道PickerType是什么类型。我写了以下内容: extension PickerItemProvider where PickerType: Equatable & SyncableEntity {
PickerType
。我编写了一个函数的重新实现,refresh(:,completion:)
,该函数在协议中定义,并在不同的协议扩展中实现
但是当我调用refresh(:,completion:)
时,不会调用新扩展中的函数,除非编译器知道PickerType
是什么类型。我写了以下内容:
extension PickerItemProvider where PickerType: Equatable & SyncableEntity {
func refresh(_ sender: Any, completion: (() -> Void)?) {
print("we're trying to have this implementation called")
PickerType.startSync()
}
}
如果我在PickerSectionProvider上调用refresh(:,completion:)
(请参阅下面我的游戏中的代码),但当我在ItemProvider上调用refresh(:,completion:)
时,它会被调用,这是一种必须符合PickerItemProvider
的泛型(再次查看下面的代码)
//当您拉入刷新时,我们正在尝试让选择器同步其提供的类型。但是我们添加的刷新(:,完成:)的实现没有被调用。
进口基金会
协议PickerItemProvider:类{
关联类型选择器类型
func findItem(按标识符:NSNumber)->PickerType?
func itemAt(indexPath:indexPath)->PickerType?
func刷新(u发送方:任何,完成:(()->无效)?)
}
扩展选择器{
func findItem(按标识符:NSNumber)->PickerType{
归零
}
公共函数刷新(u发送方:任何,完成:(()->无效)?){
打印(“默认刷新实现”)
}
}
公共类PickerSectionProvider:PickerItemProvider{
func itemAt(indexPath:indexPath)->ProvidedType{
归零
}
}
扩展PickerItemProvider,其中PickerType:Equalable&SyncableEntity{
func刷新(u发送方:任何,完成:(()->无效)?){
print(“我们试图调用此实现,而不是上面的刷新实现”)
PickerType.startSync()文件
}
}
协议同步实体{
静态函数startSync()
}
扩展同步实体{
静态函数startSync(){
}
}
类ObservationType:Equatable,SynctableEntity{
}
func==(lhs:ObservationType,rhs:ObservationType)->Bool{
返回错误
}
类GenericPickerViewController,其中ItemProvider.PickerType==PickerType{
var itemProvider:itemProvider?
init(){
}
func foo(){
//为什么我们添加的refresh(:,completion:)的实现没有在这里调用?
itemProvider?.refresh(“虚拟发件人”){
}
}
}
类PopupPickerRow,其中ItemProvider.PickerType==T{
var pickerController=genericpicpickerviewcontroller()
}
让pickerSectionProvider=pickerSectionProvider()
let row=PopupPickerRow()
row.pickerController.itemProvider=pickerSectionProvider
row.pickerController.foo()
请参见下面更正的实现
import Foundation
protocol PickerItemProvider: class {
associatedtype PickerType
func findItem(by identifier: NSNumber) -> PickerType?
func itemAt(_ indexPath: IndexPath) -> PickerType?
}
extension PickerItemProvider {
func findItem(by identifier: NSNumber) -> PickerType? {
return nil
}
func refresh(_ sender: Any, completion: (() -> Void)?) {
print("the default refresh implementation")
}
}
public class PickerSectionProvider<ProvidedType: Equatable> : PickerItemProvider {
func itemAt(_ indexPath: IndexPath) -> ProvidedType? {
return nil
}
}
extension PickerItemProvider where PickerType: Equatable & SyncableEntity {
func refresh(_ sender: Any, completion: (() -> Void)?) {
print("we’re trying to have this implementation called instead of the above implementation of refresh")
PickerType.startSync()
}
}
protocol SyncableEntity {
static func startSync()
}
extension SyncableEntity {
static func startSync() {
}
}
class ObservationType: Equatable, SyncableEntity {
}
func ==(lhs: ObservationType, rhs: ObservationType) -> Bool {
return false
}
class GenericPickerViewController<PickerType: Equatable & SyncableEntity, ItemProvider: PickerItemProvider> where ItemProvider.PickerType == PickerType {
var itemProvider: ItemProvider?
init() {
}
func foo() {
// Why doesn’t the implementation of refresh(:,completion:) we added get called here?
itemProvider?.refresh("dummy sender") {
}
}
}
class PopupPickerRow<T: Equatable & SyncableEntity, ItemProvider: PickerItemProvider> where ItemProvider.PickerType == T {
var pickerController = GenericPickerViewController<T, ItemProvider>()
}
let pickerSectionProvider = PickerSectionProvider<ObservationType>()
let row = PopupPickerRow<ObservationType, PickerSectionProvider<ObservationType>>()
row.pickerController.itemProvider = pickerSectionProvider
row.pickerController.foo()
<代码>导入基础
协议PickerItemProvider:类{
关联类型选择器类型
func findItem(按标识符:NSNumber)->PickerType?
func itemAt(indexPath:indexPath)->PickerType?
}
扩展选择器{
func findItem(按标识符:NSNumber)->PickerType{
归零
}
func刷新(u发送方:任何,完成:(()->无效)?){
打印(“默认刷新实现”)
}
}
公共类PickerSectionProvider:PickerItemProvider{
func itemAt(indexPath:indexPath)->ProvidedType{
归零
}
}
扩展PickerItemProvider,其中PickerType:Equalable&SyncableEntity{
func刷新(u发送方:任何,完成:(()->无效)?){
print(“我们试图调用此实现,而不是上面的刷新实现”)
PickerType.startSync()文件
}
}
协议同步实体{
静态函数startSync()
}
扩展同步实体{
静态函数startSync(){
}
}
类ObservationType:Equatable,SynctableEntity{
}
func==(lhs:ObservationType,rhs:ObservationType)->Bool{
返回错误
}
类GenericPickerViewController,其中ItemProvider.PickerType==PickerType{
var itemProvider:itemProvider?
init(){
}
func foo(){
//为什么我们添加的refresh(:,completion:)的实现没有在这里调用?
itemProvider?.refresh(“虚拟发件人”){
}
}
}
类PopupPickerRow,其中ItemProvider.PickerType==T{
var pickerController=genericpicpickerviewcontroller()
}
让pickerSectionProvider=pickerSectionProvider()
let row=PopupPickerRow()
row.pickerController.itemProvider=pickerSectionProvider
row.pickerController.foo()
首先,当您希望覆盖协议中声明为需求的方法
实现,并在协议
扩展
中提供一些默认实现时,它将始终调用在扩展
中实现的方法,丢弃where
clause要求。您可以看到类似的问题和
因此,要使协议
查找方法
以满足where
子句中的约束,您需要从协议
中删除方法
签名,并将其仅保留在扩展
中,就像我上面所做的那样
其次,在定义GenericPickerViewController
和PopupPickerRow
时,您错过了PickerType
要求成为可平等和可同步实体的要求,因此我也对其进行了更新。我在GenericPickerViewController
上添加了两个函数,一个用于设置PickerItemProvider
的选取类型
仅符合equalable
,另一个ider使用选取类型
符合SyncableEntity
的选取类型
设置它。这样编译器就知道哪个刷新(:,完成:)
import Foundation
protocol PickerItemProvider: class {
associatedtype PickerType
func findItem(by identifier: NSNumber) -> PickerType?
func itemAt(_ indexPath: IndexPath) -> PickerType?
}
extension PickerItemProvider {
func findItem(by identifier: NSNumber) -> PickerType? {
return nil
}
func refresh(_ sender: Any, completion: (() -> Void)?) {
print("the default refresh implementation")
}
}
public class PickerSectionProvider<ProvidedType: Equatable> : PickerItemProvider {
func itemAt(_ indexPath: IndexPath) -> ProvidedType? {
return nil
}
}
extension PickerItemProvider where PickerType: Equatable & SyncableEntity {
func refresh(_ sender: Any, completion: (() -> Void)?) {
print("we’re trying to have this implementation called instead of the above implementation of refresh")
PickerType.startSync()
}
}
protocol SyncableEntity {
static func startSync()
}
extension SyncableEntity {
static func startSync() {
}
}
class ObservationType: Equatable, SyncableEntity {
}
func ==(lhs: ObservationType, rhs: ObservationType) -> Bool {
return false
}
class GenericPickerViewController<PickerType: Equatable & SyncableEntity, ItemProvider: PickerItemProvider> where ItemProvider.PickerType == PickerType {
var itemProvider: ItemProvider?
init() {
}
func foo() {
// Why doesn’t the implementation of refresh(:,completion:) we added get called here?
itemProvider?.refresh("dummy sender") {
}
}
}
class PopupPickerRow<T: Equatable & SyncableEntity, ItemProvider: PickerItemProvider> where ItemProvider.PickerType == T {
var pickerController = GenericPickerViewController<T, ItemProvider>()
}
let pickerSectionProvider = PickerSectionProvider<ObservationType>()
let row = PopupPickerRow<ObservationType, PickerSectionProvider<ObservationType>>()
row.pickerController.itemProvider = pickerSectionProvider
row.pickerController.foo()
import Foundation
import CoreData
protocol PickerItemProvider: class {
associatedtype PickerType
func itemAt(_ indexPath: IndexPath) -> PickerType?
}
extension PickerItemProvider {
public func refresh(_ sender: Any, completion: (() -> Void)?) {
print("the default refresh implementation")
}
}
public class PickerSectionProvider<ProvidedType: Equatable> : PickerItemProvider {
func itemAt(_ indexPath: IndexPath) -> ProvidedType? {
return nil
}
}
extension PickerItemProvider where PickerType: Equatable & SyncableEntity {
func refresh(_ sender: Any, completion: (() -> Void)?) {
print("we’re trying to have this implementation called instead of the above implementation of refresh")
PickerType.startSync()
completion?()
}
}
protocol SyncableEntity {
associatedtype EntityType
static func startSync()
}
extension SyncableEntity {
static func startSync() {
print("starting sync")
}
}
class ObservationType: Equatable, SyncableEntity {
typealias EntityType = NSManagedObject
}
func ==(lhs: ObservationType, rhs: ObservationType) -> Bool {
return false
}
class GeneralPickerViewController<PickerType: Equatable, ItemProvider: PickerItemProvider> where ItemProvider.PickerType == PickerType {
private var itemProvider: ItemProvider?
private var refresher: ((Any, (() -> ())?) -> ())?
func setup<T: PickerItemProvider>(with itemProvider: T) where T.PickerType == PickerType {
refresher = { sender, completion in
itemProvider.refresh(self, completion: {
completion?()
})
}
self.itemProvider = (itemProvider as! ItemProvider)
}
func setup<T: PickerItemProvider>(with itemProvider: T) where T.PickerType == PickerType, PickerType: SyncableEntity {
refresher = { sender, completion in
itemProvider.refresh(self, completion: {
completion?()
})
}
self.itemProvider = (itemProvider as! ItemProvider)
}
func foo() {
refresher?(self, {
print("finished")
})
}
}
class PopupPickerRow<T: Equatable, ItemProvider: PickerItemProvider> where ItemProvider.PickerType == T {
var pickerController = GeneralPickerViewController<T, ItemProvider>()
}
let pickerSectionProvider = PickerSectionProvider<ObservationType>()
let row = PopupPickerRow<ObservationType, PickerSectionProvider<ObservationType>>()
row.pickerController.setup(with: pickerSectionProvider)
row.pickerController.foo()