当前位置: 首页 > 面试题库 >

swift 2.0-UITextFieldDelegate协议扩展不起作用

孟英锐
2023-03-14
问题内容

我正在尝试UITextFieldDelegate使用协议扩展在某些方法上添加默认行为,例如:

extension ViewController: UITextFieldDelegate {
    // Works if I uncommented this so I know delegates are properly set
//    func textFieldShouldReturn(textField: UITextField) -> Bool {
//        textField.resignFirstResponder()
//        return true
//    }
}

extension UITextFieldDelegate {
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        textField.resignFirstResponder()

        return true
    }
}

您可能会猜到,键盘永远不会消失。我真的看不出问题出在哪里。这是语言限制吗?有人已经成功做到了吗?

编辑:

正如@Logan所建议的,默认协议的方法实现不适用于标记为的协议@objc。但是,UITextFieldDelegate具有以下签名public protocol UITextFieldDelegate : NSObjectProtocol {...}

我已经测试了默认的实现NSObjectProtocol,它似乎运行良好:

protocol Toto: NSObjectProtocol {
    func randomInt() -> Int
}

extension Toto {
    func randomInt() -> Int {
        return 0
    }
}

class Tata: NSObject, Toto {}

let int = Tata().randomInt() // returns 0

问题答案:

我不能100%积极,但是我相信这是正在发生的事情:

无法从访问协议扩展ObjC。由于UITextFieldDelegateObjC协议,因此它依赖于ObjC调度。就编译器而言,默认实现中的方法即使存在也无法访问。

为了明确起见,我们可以扩展这些协议(如果它确实是扩展名)并增加行为。此行为只能在Swift中访问,并且绝不会出现任何问题。

问题是默认实现无法ObjC访问。

这是自定义版本的快速示例:

@objc protocol Test : class {
    func someFunc() -> String
}

extension Test {
    func someFunc() -> String {
        return ""
    }
}

// Fails here 'candidate is not @objc but protocol requires it`
class Hi : NSObject, Test {

}

Xcode建议附加,@objc但是它将一遍又一遍地建议,直到您得到@objc @objc @objc Hi : ...

根据下面的对话,我认为这很有效。我还不能完全解释原因:

@objc public protocol Toto: UITextFieldDelegate {
    optional func randomInt() -> Int
}

extension Toto {
    func randomInt() -> Int {
        return 0
    }
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        return false
    }
}

class Tata: NSObject, Toto {
}

好的,我意识到我正在考虑一个不同的问题,尽管此问题可以编译,但无法正常工作,而该问题是动态调度。如果尝试使用w
@objc或追加方法dynamic,则编译器会警告您除类之外,不能以这种方式分派。由于协议异常不符合此要求,因此ObjC调度消息发送时,无法在扩展中找到实现。

由于Swift一直在不断更新,因此适用此答案的时间是:

Swift 2.0 Xcode 7 GM



 类似资料:
  • 扩展说明 RPC 协议扩展,封装远程调用细节。 契约: 当用户调用 refer() 所返回的 Invoker 对象的 invoke() 方法时,协议需相应执行同 URL 远端 export() 传入的 Invoker 对象的 invoke() 方法。 其中,refer() 返回的 Invoker 由协议实现,协议通常需要在此 Invoker 中发送远程请求,export() 传入的 Invoker

  • 协议和扩展 你可以扩展一个已经存在的类型来采纳和遵循一个新协议, 就算是你无法访问现有类型的源代码也行. 扩展可以添加新的属性、方法和下标到已经存在的类型, 并且因此允许你添加协议需要的任何需要. protocol TextRepresentable { var textualDescription: String { get } } // 此处并无Dice这个类, 以及其sides属性

  • 问题内容: 我正在尝试使用Swift协议扩展,却发现这种行为令人困惑。您能帮我得到我想要的结果吗? 请参阅代码最后4行的注释。(如果需要,可以将其复制粘贴到Xcode7游乐场)。谢谢!! 问题答案: 简短的答案是协议扩展不执行类多态性。这是有一定道理的,因为协议可以被结构或枚举采用,并且因为我们不希望仅在没有必要的地方采用协议来引入动态调度。 因此,在中,实例变量(可能更准确地写为)并不意味着您认

  • 本文作为HPB知识库的一种扩展阅读, RLP编码是数据序列化的主要方法,本文介绍RLP编码的主要规则和原理分析,RLP编码具有较好的数据处理效率,尤其是将长度和类型统一作为前缀,实际上RLP是基于ASCII编码的一种结构化扩充,既能表示长度还能表示类型,是一种非常紧凑的结构化编码方案 RLP(Recursive Length Prefix,递归长度前缀)是一种编码算法,用于编码任意的嵌套结构的二进

  • 据我所知,协议缓冲区主要用于控制服务器和客户端代码的项目。我的一般问题是——协议缓冲区能否用于将二进制消息序列化/反序列化到使用现有协议的服务器?所以,我的问题: > 如果协议缓冲区不支持本机微调现有协议的序列化/反序列化方式,那么可以通过扩展添加该功能吗?是否可以以某种方式添加序列化/反序列化方法可以识别的关键字?也许这可以通过扩展或修改protobuf csharp port或protobuf

  • 问题内容: 我想知道在一个仅包含初始化功能并且仅打算在具体类中进行扩展的简单类中,对于等效于该初始值设定项的协议等效于什么。 因此,最简单的方法可能就是显示代码-我正在寻找与以下内容等效的协议扩展: 我期望代码看起来像这样: 我已经看到其他StackOverflow问题中建议的解决方案,但是我不确定它们是否有效,也不确定在类初始化程序中专门解决此问题。 问题答案: 您必须提供一个有效的初始化链来创