【问题标题】:Non-'@objc' method does not satisfy requirement of '@objc' protocol [duplicate]非'@objc'方法不满足'@objc'协议的要求[重复]
【发布时间】:2020-02-10 14:40:46
【问题描述】:

我已将以下内容放入 Playground 以尝试理解这一点,但我不这样做:

import Foundation

@objc protocol Sample {

    var value: Int { get set }

    func increase()
    func decrese()

}

extension Sample {

    func increase() {
        value += 1
    }

    func decrease() {
        value -= 1
    }

}

class Test: Sample {

    var value: Int = 0

}

错误出现在class Test 的声明旁边:

非'@objc'方法'increase()'不满足'@objc'协议'Sample'的要求

如果我在课堂上重新声明 increase()decrease(),则警告将被静音。或者,如果我从协议中删除声明。谁能解释一下?

编辑

我确实需要一个 Objective-C 类来符合这个协议,因此一开始是 @objc

【问题讨论】:

  • 您仅为 Swift 范围提供默认实现。因为你的协议是@objc 你的Test 类看不到默认实现
  • 由于你使用了@-objc,当你实现一个协议时,你需要在你符合协议的类中实现它的方法。此外,您可能希望对您不想在类中实现的方法使用可选的 @objc。
  • 这能回答你的问题吗? How to define optional methods in Swift protocol?

标签: ios swift


【解决方案1】:

问题是您在协议扩展中定义这些方法。这用于为协议定义一个“默认实现”(即,如果一个类型没有实现该方法,则将调用该协议的实现)。

但是 Objective-C 没有协议默认实现的概念。因此,将协议声明为 @objc 并在 Swift 协议扩展中具有默认实现是没有意义的。符合此协议的 Objective-C 类将永远无法享受这些 Swift 默认实现。

【解决方案2】:

以下代码适用于协议扩展类中的空协议方法实现

import Foundation

protocol Sample {
    var value: Int { get set }
    func increase()
    func decrease()
}

extension Sample {
    func increase() { }
    func decrease() { }
}

class Test: Sample {
    var value: Int = 0
}

或者,如果您想在扩展中使用 Sample 协议方法的一些默认实现,请使用

import Foundation

protocol Sample {
    var value: Int { get set }

    func increase()
    mutating func decrease()
}

extension Sample {
    func increase() {
        print("do anything")
    }

    mutating func decrease() {
        value -= 1
    }
}

class Test: Sample {
    var value: Int = 0
}

mutating 添加在协议方法decrease() 之前,因为它修改了协议变量value。 如果协议扩展没有修改任何协议变量(例如increase()),则不需要mutating关键字

【讨论】:

  • 当协议未声明@objc 时,它没有问题,但正如我所说,我需要它可以被 ObjC 访问。 @Rob 是对的。 ObjC 对协议扩展一无所知,因此需要重新声明实现
猜你喜欢
  • 2017-01-22
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多