use*_*008 49 protocols class swift
这两个宣言
protocol SomeProtocol : AnyObject {
}
Run Code Online (Sandbox Code Playgroud)
和这个宣言
protocol SomeProtocol : class {
}
Run Code Online (Sandbox Code Playgroud)
似乎使它只有类可以符合这个协议(即协议的实例是对象的引用),并没有其他效果.
它们之间有什么区别吗?一个人应该优先于另一个吗?如果没有,为什么有两种方法可以做同样的事情?
我正在使用最新发布的Xcode 6.3.1.
Cod*_*aFi 12
关于答案https://forums.swift.org/t/class-only-protocols-class-vs-anyobject/11507/4,不推荐这个答案.这些话现在都是一样的.
弃用
更新:在咨询权力之后,这两个定义应该是等价的,并AnyObject在完成时用作替身class.在未来,后者将消除前者,但目前,它们确实存在一些细微差别.
不同之处在于@objc声明的语义.因为AnyObject,期望符合类可能是也可能不是正确的Objective-C对象,但语言无论如何都将它们视为对待(因为有时你会失去静态调度).从中可以看出,你可以治疗AnyObject等人.协议约束作为一种请求@objc成员函数的方法,如AnyObjectSTL 中的文档中的示例所示:
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. // <===
}
Run Code Online (Sandbox Code Playgroud)
如果您将其更改为class-deriving协议,则相同的示例会立即失效:
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'
}
Run Code Online (Sandbox Code Playgroud)
因此,当您只关心引用语义而不关心动态成员查找或Objective-C桥接时,似乎应该使用class更保守的版本AnyObject.
在斯威夫特编程语言指南的协议,下的类只有协议部分。它只提到了AnyObject,但没有提到class。
通过将AnyObject协议添加到协议的继承列表中,可以将协议采用限制为类类型(而不是结构或枚举)。
protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {
// class-only protocol definition goes here
}
Run Code Online (Sandbox Code Playgroud)
因此,我建议将AnyObjectover class用于新代码或新项目。除此之外,我看不出它们之间有任何明显的区别。
我之前说错了。@MartinR 确实应该回答这个问题,因为他是纠正我并提供正确信息的人。
真正的区别在于带有类限定符的协议只能应用于类,而不能应用于结构或枚举。
马丁,你为什么不回答,OP 可以接受你的回答?