这个宣言
protocol SomeProtocol : AnyObject {
}
和这个声明
protocol SomeProtocol : class {
}
似乎使得只有类才能符合这个协议(即协议的实例是对象的引用),并且没有其他效果。
它们之间有什么区别吗?一个人应该优先于另一个吗?如果没有,为什么有两种方法可以做同样的事情?
我正在使用最新发布的Xcode 6.3.1。
答案 0 :(得分:10)
关于答案https://forums.swift.org/t/class-only-protocols-class-vs-anyobject/11507/4,此答案已弃用。这些话现在都是一样的。
<强> DEPRECATED 强>
更新:咨询the powers that be后,两个定义假设等同,/*Correct Me If I am wrong*/
被用作替代,AnyObject
是完成了。在未来,后者将消除前者,但目前,它们确实存在一些细微差别。
区别在于class
声明的语义。对于@objc
,期望符合类可能是也可能不是正确的Objective-C对象,但语言无论如何都将它们视为对待(因为有时你会丢失静态调度)。从中可以看出,你可以对待AnyObject
等人。协议约束作为一种询问AnyObject
成员函数的方法,如STL中@objc
文档中的示例所示:
AnyObject
如果将其更改为import Foundation
class C {
@objc func getCValue() -> Int { return 42 }
}
// If x has a method @objc getValue()->Int, call it and
// return the result. Otherwise, return nil.
func getCValue1(x: AnyObject) -> Int? {
if let f: ()->Int = x.getCValue { // <===
return f()
}
return nil
}
// A more idiomatic implementation using "optional chaining"
func getCValue2(x: AnyObject) -> Int? {
return x.getCValue?() // <===
}
// An implementation that assumes the required method is present
func getCValue3(x: AnyObject) -> Int { // <===
return x.getCValue() // x.getCValue is implicitly unwrapped. // <===
}
- 派生协议:
class
所以似乎import Foundation
protocol SomeClass : class {}
class C : SomeClass {
@objc func getCValue() -> Int { return 42 }
}
// If x has a method @objc getValue()->Int, call it and
// return the result. Otherwise, return nil.
func getCValue1(x: SomeClass) -> Int? {
if let f: ()->Int = x.getCValue { // <=== SomeClass has no member 'getCValue'
return f()
}
return nil
}
// A more idiomatic implementation using "optional chaining"
func getCValue2(x: SomeClass) -> Int? {
return x.getCValue?() // <=== SomeClass has no member 'getCValue'
}
// An implementation that assumes the required method is present
func getCValue3(x: SomeClass) -> Int { // <===
return x.getCValue() // <=== SomeClass has no member 'getCValue'
}
是class
的更保守的版本,当你只关心引用语义而不关心动态成员查找或Objective-C桥接时,应该使用它。
答案 1 :(得分:7)
这是由Swift forums上的Swift官方开发人员(Slava_Pestov)回答的。这是摘要:
您应该使用AnyObject
(protocol SomeProtocol: AnyObject
)。
AnyObject
和class
是等效的。没有区别。
class
最终将被弃用。答案 2 :(得分:4)
AnyObject
是所有类隐式符合的协议(source)。所以我想说没有区别:你可以使用任何一种来要求类约束。
答案 3 :(得分:4)
在Swift programming language guide for protocols的仅限类协议部分下。它只提到了AnyObject
,但没有提到class
。
通过将AnyObject协议添加到协议的继承列表,可以将协议采用限制为类类型(而不是结构或枚举)。
protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {
// class-only protocol definition goes here
}
出于这个原因,我建议使用AnyObject
而不是class
来获取新代码或新项目。除此之外,我认为他们之间没有任何明显的区别。
答案 4 :(得分:2)
答案 5 :(得分:0)
我之前错过了。 @MartinR应该真的回答这个问题,因为他是纠正我并提供正确信息的人。
真正的区别在于具有类限定符的协议只能应用于类,而不能应用于结构或枚举。
马丁,你为什么不回答,OP可以接受你的回答?答案 6 :(得分:0)
如果您在class
行中的protocol P: class {}
的Xcode 9中打开帮助(按住Alt键单击),您将获得typealias AnyObject
。
因此,无论您将协议约束为class
还是AnyObject
,编译的代码(在Swift 4中)都是相同的。
也就是说,还有 style 和 future options 的问题 - 未来的Swift版本可能需要处理class
和AnyObject
以某种微妙的方式不同,即使现在情况并非如此。