简体   繁体   English

如何定义Swift协议,以便实现可以是属性或方法?

[英]How can I define a Swift Protocol so that the implementation can be a property _or_ a method?

Here's what I want to do: 这是我想做的:

import Foundation
import UIKit

protocol PlayableMediaItem {
    func title() -> String
    func albumArt() -> UIImage
    func audioFileURL() -> URL
}


struct AudioTrack : Codable, PlayableMediaItem {
    var title: String
    var desc:String
    var albumArtDemoName:String
    var audioDemoFilename:String

    func albumArt() -> UIImage {
        let image = UIImage(named: albumArtDemoName)
        return image!
    }

    func audioFileURL() -> URL {
        return Bundle.main.url(forResource: audioDemoFilename, withExtension: "mp3")!
    }
}

But I get the error that AudioTrack doesn't conform to the PlayableMediaItem protocol because the title property isn't a method, it's a property. 但是我得到一个错误,即AudioTrack不符合PlayableMediaItem协议,因为title属性不是方法,而是属性。

How can I set this up so that title , albumArt , etc. can be implemented as either properties or methods, so long as they give me back the right type? 我怎样才能设置这让titlealbumArt等均可实现为属性或方法,只要他们给我回到正确的类型?

Some of my implementations of this might just be properties, while others are computed. 我对此的一些实现可能只是属性,而其他实现是经过计算的。

Just declare it as a property in the protocol, and use a computed property instead of using a method: 只需在协议中将其声明为属性,然后使用计算的属性而不是使用方法即可:

import Foundation
import UIKit

protocol PlayableMediaItem {
    var title: String { get } 
    var albumArt: UIImage { get }
    var audioFileURL: URL { get }
}


struct AudioTrack : Codable, PlayableMediaItem {
    var title: String
    var desc:String
    var albumArtDemoName:String
    var audioDemoFilename:String

    var albumArt: UIImage {
        let image = UIImage(named: albumArtDemoName)
        return image!
    }

    var audioFileURL: URL {
        return Bundle.main.url(forResource: audioDemoFilename, withExtension: "mp3")!
    }
}

Change your protocol to use properties instead of functions. 更改您的协议以使用属性而不是函数。 That way implementing struct/class can decide to have it implemented as real property or computed one. 通过这种方式,实现struct / class可以决定将其实现为不动产还是经过计算的财产。

protocol PlayableMediaItem {
    var title: String { get }
    var albumArt: UIImage { get }
    var audioFileURL: URL { get }
}

Not entirely sure what you need, since it depends but maybe try making them variables instead of funcs and then on classes that implement the protocol you can manipulate their get/set of the var. 并不是完全确定您需要什么,因为这取决于但可以尝试使它们成为变量而不是funcs,然后在实现该协议的类上可以操纵其var的获取/设置。

struct Square {
 var edge: Double = 0
 var area: Double {
get {
  return edge * edge
}
set {
  edge = sqrt(newValue)
}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在swift可选中创建协议方法? - How can I make a protocol method in swift optional? 如何使用Swift协议调用NSStringFromProtocol? - How can I call NSStringFromProtocol with a Swift protocol? 如何使通用协议在 Swift 中不通用? 所以我可以将它用作参数类型 - How to make generic protocol not generic in Swift? So I can use it as parameter type 我可以在Swift中声明函数,然后再定义它们的实现吗? - Can I declare functions in Swift and later define their implementation? 如何遵循Swift中的Strideable协议? - How can I conform to the Strideable protocol in Swift? 如果带有实现的扩展如下,我应该定义协议内部的计算属性吗? - Should I define computed property of inside of protocol if the extension with implementation follows? 如何定义一个专门用于泛型协议的协议,以便它可以用于类型声明? - How to define a protocol that specializes a generic protocol, so that it can be used in type declarations? 协议默认实现可以覆盖方法吗? - Can a method be overridden by protocol default implementation? 如何在Swift中定义自定义UIGestureRecognizer? - How can I define the custom UIGestureRecognizer in Swift? 如何使现有的类成员成为协议实现? - How can I make an existing class member be a protocol implementation?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM