Ios 为什么Swift纯类协议需要任何对象继承?
我正试图找出Swift文档: 但我坚持这个问题,为什么需要任何对象,我的意思是为什么我需要使用那种限制? 不限制值和引用类型只是不使用任何对象是不是一个坏主意Ios 为什么Swift纯类协议需要任何对象继承?,ios,swift,Ios,Swift,我正试图找出Swift文档: 但我坚持这个问题,为什么需要任何对象,我的意思是为什么我需要使用那种限制? 不限制值和引用类型只是不使用任何对象是不是一个坏主意 protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol { // class-only protocol definition goes here } 任何人都可以解释一些代码的例子,特别是将是非常有帮助的。谢谢 顺便说一句,这个答案可能很好,但字面上的
protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {
// class-only protocol definition goes here
}
任何人都可以解释一些代码的例子,特别是将是非常有帮助的。谢谢
顺便说一句,这个答案可能很好,但字面上的解释让我感到困惑
编写协议时,为采用或符合协议的类型定义接口:
struct Bell: Greeter {
let greeting = "Ding!"
}
class Person: Greeter {
let greeting: String
init(name: String) {
greeting = "Welcome! My name is \(name)."
}
}
var store = Store(name: "My Shop", address: "123 Main St.", greeter: Bell())
store.greeter.greet() // => "Ding!"
store.greeter = Person(name: "Itai")
store.greeter.greet() // => "Welcome! My name is Itai."
//每个问候者都有问候语
//以及它表达这一信息的方式。
礼宾接待员{
变量问候语:字符串{get}
func
}
接机分机{
//'greet'方法的默认实现。
func{
打印(自我问候)
}
}
这使符合的每种类型都具有一致的行为,并允许您以相同的方式对待它们,而不管它们是什么。例如,类型可以存储绑定到协议类型的值:
struct存储{
//商店的名称。
变量名称:String
//商店的地址。
变量地址:字符串
//顾客进来时向他们打招呼的实体。
迎宾员:迎宾员
}
在这种情况下,Store.greeter
可以设置为符合greeter
协议的任何值或对象:
struct Bell: Greeter {
let greeting = "Ding!"
}
class Person: Greeter {
let greeting: String
init(name: String) {
greeting = "Welcome! My name is \(name)."
}
}
var store = Store(name: "My Shop", address: "123 Main St.", greeter: Bell())
store.greeter.greet() // => "Ding!"
store.greeter = Person(name: "Itai")
store.greeter.greet() // => "Welcome! My name is Itai."
默认情况下,值类型和对象类型都可以采用协议,即struct
s和class
es。这是一个很好的默认值,因为在许多情况下,没有理由限制谁可以遵守协议
然而,有一种情况是,这很重要。默认情况下,Store
拥有其greeter
属性,即当您将对象分配给Store.greeter
时,该属性将被保留。这通常很好,除非您具有潜在的循环关系(例如,如果Person
引用了他们工作的存储
)
通常,要打破这样一个潜在的循环链,您将使变量变弱
:
struct存储{
// ...
迎接者:迎接者?
//^错误:“弱”不能应用于非类绑定的“GrETER”;考虑添加具有类绑定的协议一致性。
}
但是,如果您尝试此操作,您将得到上述错误。这是因为weak
只对对象有意义,而对struct
s没有意义(struct
s只能被拥有,因为它们是值类型-每个所有者只复制一个struct
,所以没有一个中心值可以保留或释放)。在这种情况下,要确保弱
引用,必须确保问候者
仅为对象类型
实现这一点的方法是通过使用AnyObject
作为约束来约束协议,使其仅允许类符合:
协议接线员:AnyObject{
// ...
}
现在,Bell
不再符合Greeter
(错误:非类类型“Bell”不能符合类协议“Greeter”
),但允许将弱变量Greeter:Greeter?
作为变量
那么,什么时候应该将协议限制为“类绑定”(使用
AnyObject
)呢?好吧,只有当你真的需要的时候。类绑定协议的一个好处是允许弱
引用它们,其主要用例是使用委托引用来防止循环保留
例如,UITableView
具有一个弱委托
属性,因为委托
对象通常是拥有UITableView
对象本身的视图控制器。如果视图控制器保留了表视图,而表视图保留了控制器,则两者都不能自动释放
因此,在一般情况下,您不需要担心AnyObject
约束,除非您确实只希望类符合协议。编写协议时,您为采用或符合协议的类型定义接口:
struct Bell: Greeter {
let greeting = "Ding!"
}
class Person: Greeter {
let greeting: String
init(name: String) {
greeting = "Welcome! My name is \(name)."
}
}
var store = Store(name: "My Shop", address: "123 Main St.", greeter: Bell())
store.greeter.greet() // => "Ding!"
store.greeter = Person(name: "Itai")
store.greeter.greet() // => "Welcome! My name is Itai."
//每个问候者都有问候语
//以及它表达这一信息的方式。
礼宾接待员{
变量问候语:字符串{get}
func
}
接机分机{
//'greet'方法的默认实现。
func{
打印(自我问候)
}
}
这使符合的每种类型都具有一致的行为,并允许您以相同的方式对待它们,而不管它们是什么。例如,类型可以存储绑定到协议类型的值:
struct存储{
//商店的名称。
变量名称:String
//商店的地址。
变量地址:字符串
//顾客进来时向他们打招呼的实体。
迎宾员:迎宾员
}
在这种情况下,Store.greeter
可以设置为符合greeter
协议的任何值或对象:
struct Bell: Greeter {
let greeting = "Ding!"
}
class Person: Greeter {
let greeting: String
init(name: String) {
greeting = "Welcome! My name is \(name)."
}
}
var store = Store(name: "My Shop", address: "123 Main St.", greeter: Bell())
store.greeter.greet() // => "Ding!"
store.greeter = Person(name: "Itai")
store.greeter.greet() // => "Welcome! My name is Itai."
默认情况下,值类型和对象类型都可以采用协议,即struct
s和class
es。这是一个很好的默认值,因为在许多情况下,没有理由限制谁可以遵守协议
然而,有一种情况是,这很重要。默认情况下,Store
拥有其greeter
属性,即当您将对象分配给Store.greeter
时,该属性将被保留。这通常很好,除非您具有潜在的循环关系(例如,如果Person
引用了他们工作的存储
)
通常,要打破这样一个潜在的循环链,您将使变量变弱
:
struct存储{
// ...
迎接者:迎接者?
//^error:不能应用“弱”