Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 为什么Swift纯类协议需要任何对象继承?_Ios_Swift - Fatal编程技术网

Ios 为什么Swift纯类协议需要任何对象继承?

Ios 为什么Swift纯类协议需要任何对象继承?,ios,swift,Ios,Swift,我正试图找出Swift文档: 但我坚持这个问题,为什么需要任何对象,我的意思是为什么我需要使用那种限制? 不限制值和引用类型只是不使用任何对象是不是一个坏主意 protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol { // class-only protocol definition goes here } 任何人都可以解释一些代码的例子,特别是将是非常有帮助的。谢谢 顺便说一句,这个答案可能很好,但字面上的

我正试图找出Swift文档:

但我坚持这个问题,为什么需要任何对象,我的意思是为什么我需要使用那种限制? 不限制值和引用类型只是不使用任何对象是不是一个坏主意

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:不能应用“弱”