我正在看一个教程,我注意到作者扩展了他们的名为Activity的协议,并在他们的代码中编写了函数体。这是编译的,但是我的印象是协议只显示方法签名,或者如果它实现了主体,那么它将是一个变异函数。下面的代码没有在它的一个函数上使用变异,但它仍然可以运行和工作!有人能解释这些现象或确认协议扩展可以有方法体吗?
import CareKit
import SwiftyJSON
enum ActivityType: String {
case Intervention
case Assessment
}
enum ScheduleType: String {
case Weekly
case Daily
}
enum StepFormat : String {
case Scale
case Quantity
}
protocol Activity {
var identifier : String { get set}
var groupIdentifier : String { get set}
var title : String { get set}
var colour : UIColor? { get set}
var text : String { get set}
var startDate : Date { get set}
var schedule : [NSNumber] { get set}
var scheduleType : ScheduleType { get set}
var instructions : String? { get set}
var imageURL : NSURL? { get set}
var activityType: ActivityType { get set}
var medication : Medication? { get set}
init()
init(json: JSON)
func createCareKitActivity() -> OCKCarePlanActivity
}
extension Activity {
// A mutating function to allow Acticities or Assessments to intialiser base properties
mutating func parseActivityFields(json: JSON) {
self.identifier = json["identifier"].string!
self.groupIdentifier = json["group_identifier"].string!
self.title = json["title"].string!
self.text = json["text"].string!
let colourString = json["color"].string!
self.colour = UIColor.colorWithString(colourString)
if let instructionString = json["instructions"].string {
self.instructions = instructionString
}
if let imageString = json["imageURL"].string {
let componentsOfString = imageString.components(separatedBy: ".")
if let pathForResource = Bundle.main.path(forResource: componentsOfString[0], ofType: componentsOfString[1]){
self.imageURL = NSURL(fileURLWithPath: pathForResource)
}
}
self.startDate = dateFromString(string: json["startdate"].string!)!
self.scheduleType = ScheduleType(rawValue: json["scheduletype"].string!)!
self.schedule = json["schedule"].string!.components(separatedBy: ",").map ( {
NSNumber(value: Int32($0)!)
})
if let medication = json["medication"].string,
let medicationImageString = json["medicationimage"].string {
let componentsOfString = medicationImageString.components(separatedBy: ".")
let pathForResource = Bundle.main.path(forResource: componentsOfString[0], ofType: componentsOfString[1])
self.medication = Medication.init(medication: medication, imageURL: NSURL.init(fileURLWithPath: pathForResource!))
}
}
init(json: JSON) {
self.init()
self.parseActivityFields(json: json)
}
func createCareKitActivity() -> OCKCarePlanActivity{
//creates a schedule based on the internal values for start and end dates
let startDateComponents = NSDateComponents(date: self.startDate, calendar: NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)! as Calendar)
let activitySchedule: OCKCareSchedule!
switch self.scheduleType {
case .Weekly :
activitySchedule = OCKCareSchedule.weeklySchedule(withStartDate: startDateComponents as DateComponents, occurrencesOnEachDay: self.schedule)
case .Daily:
activitySchedule = OCKCareSchedule.dailySchedule(withStartDate: startDateComponents as DateComponents, occurrencesPerDay: self.schedule[0].uintValue)
}
let activity = OCKCarePlanActivity.intervention(
withIdentifier: identifier,
groupIdentifier: nil,
title: title,
text: text,
tintColor: colour,
instructions: instructions,
imageURL: imageURL as? URL,
schedule: activitySchedule,
userInfo: ["medication": medication], optional: false)
return activity
}
}发布于 2018-10-13 11:38:57
在Swift中,扩展允许您为协议提供默认实现。
根据Swift关于协议的文档,
可以对
协议进行扩展,以提供符合类型的方法、初始值设定项、下标和计算属性实现。这允许您在协议本身上定义行为,而不是在每个类型的单独一致性或全局函数中定义行为。
发布于 2018-10-22 15:00:59
In Swift, does a protocol extension allow function bodies?
是。这是一种非常方便的方式,可以将特定的功能仅添加到某些协议的实例中。请考虑以下内容:
protocol Flying {
func useWings()
}
extension Flying {
func fly() {}
}
class Animal {}
class Bird: Animal {}
extension Bird: Flying {
func useWings() {}
}
let bird = Bird()
bird.fly()这里也有一些逻辑。如果什么东西可以使用翅膀,那么它可能也会飞。因此,当我们扩展Bird来实现Flying时,就像它有useWings一样--它现在也可以飞了。
The code below doesn't use mutating on one of its functions but it still runs and WORKS! Can someone explain the phenomena
Mutating关键字表示该函数将改变其被调用的值。如果你的协议不是一个类(protocol Some: class {}),你必须明确地说出来。createCareKitActivity()不会自我变异,因此您不必指定mutating
发布于 2020-10-10 03:39:33
Class -> Protocol -> ExtensionSwift的protocol extension允许您的类通过附加或默认函数进行操作
https://stackoverflow.com/questions/52789231
复制相似问题