Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 重新实现协议扩展中添加的函数isn’;我没打电话_Swift - Fatal编程技术网

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()