Class 什么';从任何对象扩展的协议和仅类协议之间的区别是什么?

Class 什么';从任何对象扩展的协议和仅类协议之间的区别是什么?,class,swift,protocols,Class,Swift,Protocols,这两项声明 protocol SomeProtocol : AnyObject { } protocol SomeProtocol : class { } 还有这个宣言 protocol SomeProtocol : AnyObject { } protocol SomeProtocol : class { } 似乎只有类才能符合此协议(即协议的实例是对对象的引用),并且没有其他影响 他们之间有什么区别吗?一个应该优先于另一个吗?如果不是,为什么有两种方法做同样的事情 我使用的是最新发布

这两项声明

protocol SomeProtocol : AnyObject {
}
protocol SomeProtocol : class {
}
还有这个宣言

protocol SomeProtocol : AnyObject {
}
protocol SomeProtocol : class {
}
似乎只有类才能符合此协议(即协议的实例是对对象的引用),并且没有其他影响

他们之间有什么区别吗?一个应该优先于另一个吗?如果不是,为什么有两种方法做同样的事情


我使用的是最新发布的Xcode 6.3.1。

我以前说错了@马丁纳真的应该回答这个问题,因为他是纠正我并提供正确信息的人

真正的区别在于,带有类限定符的协议只能应用于类,而不能应用于结构或枚举


Martin,你为什么不回答,OP可以接受你的回答?

AnyObject
是一个所有类都隐式符合的协议()。所以我想说没有区别:您可以使用任意一个来要求类约束。

关于答案,这个答案是不推荐的。这些词现在都一样了

已弃用

更新:在咨询之后,这两个定义应该是等效的,在完成
class
时,
AnyObject
被用作替身。在未来,后者将取代前者,但就目前而言,它们确实存在一些细微的差异

区别在于
@objc
声明的语义。对于
AnyObject
,我们期望一致性类可能是也可能不是合适的Objective-C对象,但语言还是这样对待它们(因为有时会丢失静态分派)。这样做的好处是,您可以将
AnyObject
等协议约束视为请求
@objc
成员函数的一种方式,如STL中
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
AnyObject
的一个更保守的版本,当您只关心引用语义而不关心动态成员查找或Objective-C桥接时,应该使用它。

中的,在仅类协议部分下。它只提到了
AnyObject
,但没有提到
class

通过将AnyObject协议添加到协议的继承列表,可以将协议采用限制为类类型(而不是结构或枚举)

出于这个原因,我建议对新代码或新项目使用
AnyObject
over
class
。除此之外,我看不出他们之间有什么明显的区别

如果在Xcode 9中打开
的帮助(alt单击),如
协议p:class{}
,您将得到
类型别名AnyObject

因此,无论您将协议约束为
class
还是
AnyObject
,编译的代码(在Swift 4中)都是相同的

也就是说,还有风格和未来选择的问题——未来的Swift版本可能希望以某种微妙的方式以不同的方式对待
任何对象
,即使现在不是这样


(编辑:这最终发生在Swift 5.4/Xcode 12.5中。)

这是由官方Swift开发人员(Slava_Pestov)在网站上回答的。总结如下:

  • 您应该使用
    AnyObject
    协议SomeProtocol:AnyObject

  • AnyObject
    class
    是等效的。没有区别

  • class
    最终将被弃用


从2021年开始,Xcode 12.5,Big Sur OS:

苹果公司不赞成使用
class

改用
AnyObject

快乐编码


但似乎从任何对象继承的协议也只能应用于类,而不能应用于结构或枚举<代码>协议SomeProtocol:AnyObject{};struct Foo:SomeProtocol{}给出编译器错误
非类类型“Foo”不能符合类协议“SomeProtocol”
。(我觉得实际上没有区别,但我无法证明。)我想这是有道理的,因为任何对象也只是类对象。如果希望结构或枚举符合该协议,则必须使用
protocolsomeprotocol:Any
。让我想知道类限定符的意义是什么。我(错误地)认为它将协议限制在类上,而不是类的实例上,但文档清楚地说明了其他情况。真正的区别是,带有类限定符的协议只能应用于类,而不能应用于结构或枚举?不,这没有什么区别,对于
AnyObject
也一样,因为只有对象可以符合这一点,在
AnyObject
需要的地方,既不能使用枚举,也不能使用结构。真正的区别在于
AnyObject
可以是Swift类或Obj-C对象(或其他符合该协议的对象),但只有Swift类才能符合
class
。首先,感谢您的回答。(也许不应该使用“AnyClass”,因为它已经是AnyObject.type的类型别名。)现在清楚了
AnyObject
和定义为
protocol-MyClassProtocol:class{}
MyClassProtocol
之间的区别。我仍然缺少的是
protocol-MyObjectProtocol:AnyObject{}
protocol-MyClassProtocol:class{}
之间的区别。我仍然在努力(这可能是我的错)找到一个具体的例子,其中
protocol-protocol:AnyObject{}
不能与
protocol-protocol:class{}互换
。那么你现在的结论是什么?如果我对乔·格罗夫的理解正确,那么
protocolsomeprotocol:AnyObject{}
protocolsomeprotocol:class{}之间没有区别<