为什么我不能在协议中声明动态变量
Why can't I declare dynamic variable inside protocol
我目前正在为我的 object 开发协议,它继承自 Realm 的 Object
。在我的 object 中我有变量,这些变量被标记为 @objc dynamic
@objc dynamic var title: String = ""
现在想象一下我有更多具有相同变量 title
的相似 object 的情况。我想为他们创建协议,因为我只想使用一种泛型方法来更改 object.
的标题
所以,我创建了带有 title
变量标记为 @objc dynamic
的协议,并期望它是这样工作的
protocol Titleable: class {
@objc dynamic var title: String { get set }
}
...这没有成功,我实际上收到了两个错误。
关于将变量标记为 @objc
@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes
...我可以通过将协议标记为 @objc
来解决这个问题。
但是我仍然遇到与 dynamic
关键字相关的错误
Only members of classes may be dynamic
...我认为当我为 classes 约束协议时,它应该没问题,但是...它不是。
我通过删除 @objc
以及 dynamic
关键字以某种方式解决了这个问题
protocol Titleable: class {
var title: String { get set }
}
...行得通。我可以在实现此协议的 class 中将变量标记为 @objc dynamic
。
class Item: Object, Titleable {
@objc dynamic var title: String = ""
}
但是,我不确定为什么这有效,为什么在协议声明中将变量标记为 dynamic
无效。我将不胜感激任何解释。
看看什么dynamic
means:
dynamic
Apply this modifier to any member of a class that can be represented
by Objective-C. When you mark a member declaration with the dynamic
modifier, access to that member is always dynamically dispatched using
the Objective-C runtime. Access to that member is never inlined or
devirtualized by the compiler.
Because declarations marked with the dynamic modifier are dispatched
using the Objective-C runtime, they must be marked with the objc
attribute.
请特别注意第一段。它说标记为 dynamic
的东西不能被静态调度。现在考虑我在模块中有一些 class 的情况。它已经被编译,并且它的方法是静态调度的。现在考虑另一个模块,它使 class 符合某些包含 dynamic
方法的协议。这怎么行?该方法已 已经 在某些地方静态调度。它不能追溯转换为动态调度。 (这同样适用于同一模块中的声明,具体取决于编译器标志和访问级别,但我发现解释跨模块更容易。)
在任何情况下您想要这样做的主要原因是确保您可以在 属性 上使用 KVO。 (如果您有其他原因需要强制符合类型使用动态 属性,我很想知道用例。)如果这是您的目标,我可能会要求 Titleable
符合NSObjectProtocol
.
我目前正在为我的 object 开发协议,它继承自 Realm 的 Object
。在我的 object 中我有变量,这些变量被标记为 @objc dynamic
@objc dynamic var title: String = ""
现在想象一下我有更多具有相同变量 title
的相似 object 的情况。我想为他们创建协议,因为我只想使用一种泛型方法来更改 object.
所以,我创建了带有 title
变量标记为 @objc dynamic
的协议,并期望它是这样工作的
protocol Titleable: class {
@objc dynamic var title: String { get set }
}
...这没有成功,我实际上收到了两个错误。
关于将变量标记为 @objc
@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes
...我可以通过将协议标记为 @objc
来解决这个问题。
但是我仍然遇到与 dynamic
关键字相关的错误
Only members of classes may be dynamic
...我认为当我为 classes 约束协议时,它应该没问题,但是...它不是。
我通过删除 @objc
以及 dynamic
关键字以某种方式解决了这个问题
protocol Titleable: class {
var title: String { get set }
}
...行得通。我可以在实现此协议的 class 中将变量标记为 @objc dynamic
。
class Item: Object, Titleable {
@objc dynamic var title: String = ""
}
但是,我不确定为什么这有效,为什么在协议声明中将变量标记为 dynamic
无效。我将不胜感激任何解释。
看看什么dynamic
means:
dynamic
Apply this modifier to any member of a class that can be represented by Objective-C. When you mark a member declaration with the dynamic modifier, access to that member is always dynamically dispatched using the Objective-C runtime. Access to that member is never inlined or devirtualized by the compiler.
Because declarations marked with the dynamic modifier are dispatched using the Objective-C runtime, they must be marked with the objc attribute.
请特别注意第一段。它说标记为 dynamic
的东西不能被静态调度。现在考虑我在模块中有一些 class 的情况。它已经被编译,并且它的方法是静态调度的。现在考虑另一个模块,它使 class 符合某些包含 dynamic
方法的协议。这怎么行?该方法已 已经 在某些地方静态调度。它不能追溯转换为动态调度。 (这同样适用于同一模块中的声明,具体取决于编译器标志和访问级别,但我发现解释跨模块更容易。)
在任何情况下您想要这样做的主要原因是确保您可以在 属性 上使用 KVO。 (如果您有其他原因需要强制符合类型使用动态 属性,我很想知道用例。)如果这是您的目标,我可能会要求 Titleable
符合NSObjectProtocol
.