1.定义和语法
protocol SomeProtocol { // protocol definition goes here }
2. 语法
当自定义的类型需要遵守一个或多个协议时,结构如下:
class CustomType:SuperClass,Protocol1,Protocol2 {
}
3. 属性要求
protocol SomeProtocol { var mustBeSettable: Int { get set } var doesNotNeedToBeSettable: Int { get } static var someTypeProperty:Int { get set } } protocol FullNamed { var fullName:String {get} } class Person: FullNamed { var prefix:String? var name:String init(name:String,prefix:String?) { self.prefix = prefix self.name = name } var fullName:String { return (prefix != nil ? prefix! + name : name) } }
protocol FullNamed { var fullName:String {get} mutating func fixname() } struct boy:FullNamed { var prefix:String var name:String var fullName:String { return(prefix + name) } mutating func fixname() { self.name = "123" } } var b = boy(prefix: "China",name: "Barry") print(b.fullName) b.fixname() print(b.fullName)结果:
ChinaBarry
China123
5.可选属性与可选方法:
根据上面3,4结论,在协议中定义的方法我要必须全部实现,但这很不合理。在OC的协议中就存在可选方法。
在swift中我们可以定义具有可选的属性和方法,但是这样的协议只能用于class. 定义这样的协议时要在协议的定义前加上@objc
@objc public protocol FullNamed { func beautiful() optional var fullName:String {get} optional func fixname() } class Person:NSObject,FullNamed { var prefix:String? var name:String var age:Int func beautiful() { } init(name:String,prefix:String?) { self.prefix = prefix self.name = name self.age = 2 } }
上面的代码中 person继承于NSObject,但是如果Person没有继承于NSObject及其子类,那么就要在实现的方法前面加是@objc
class Person:FullNamed { var prefix:String? var name:String var age:Int @objc func beautiful() { } init(name:String,prefix:String?) { self.prefix = prefix self.name = name self.age = 2 } }
6. 在协议中添加初始化方法
在协议中可以添加一个初始化方法,这个方法在实现时需要加上关键字required。例如:我们自定一个类遵守了NSCoding协议,那么我们就必须在类中实现
在类Person中有一个 RandomProtocol类型的属性,任何遵守RandomProtocol协议的类的实例都可以作为RandomProtocol类型的实例。就像上面代码表现的一样,CreateNumber()和ResetNumber()都可以作为RandomProtocol类型的实例
publicinit?(coder aDecoder:NSCoder)
requiredinit?(coder aDecoder:NSCoder) {
super.init(coder: aDecoder)
}
当我们继承的父类也实现了这个方法是,我们就需要变成requiredoverride
7. 协议作为一种类型:
protocol RandomProtocol { func getARandom()->Int } // 用于产生一个随机数,遵守RandomProtocol协议 class CreateNumber:RandomProtocol { func getARandom() -> Int { return random() } } // 返回一个0,遵守RandomProtocol协议 class ResetNumber:RandomProtocol { func getARandom() -> Int { return 0 } } class Person { let name:String! // 协议作为属性的类型 let random:RandomProtocol init(name:String,random:RandomProtocol) { self.name = name self.random = random } func outNumber()->Int { return self.random.getARandom() } } let p = Person(name: "iOS",random:CreateNumber()) print(p.outNumber()) let p1 = Person(name: "iOS",random:ResetNumber()) print(p1.outNumber())
在类Person中有一个 RandomProtocol类型的属性,任何遵守RandomProtocol协议的类的实例都可以作为RandomProtocol类型的实例。就像上面代码表现的一样,CreateNumber()和ResetNumber()都可以作为RandomProtocol类型的实例
8. 代理
遵守某个协议的类可以作为代理出现,只要用过tableView对这个再熟悉不过了。在tableView中有这样两个属性
weakpublicvar dataSource:UITableViewDataSource?
weak publicvar delegate:UITableViewDelegate?
当我们的UIViewcontroller加入tableView时,我们只需要让UIViewcontroller遵守UITableViewDelegate和UITableViewDataSourceDelegates就可以作为tableView的代理
tableView.
self.tableView.delegate =self
self.tableView.dataSource =self
9. 其他
-
protocolSomeClassOnlyProtocol:class, SomeInheritedProtocol {
-
// class-only protocol definition goes here
-
}