swift - 如何解决此构建问题 - 无法分配给属性 : 'date' is a get only property

标签 swift

class Event {

    var name : String?
    var FullDate : NSDate?

    var date: String? {
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "EEEE MMM dd"
        return dateFormatter.stringFromDate(FullDate!)
    }

    init ()
}


class EventsViewController: UIViewController, UITableViewDelegate , UITableViewDataSource 
{
    let Event1 = Event()

    override func viewDidLoad() {
        super.viewDidLoad()
        Event1.date = "10.01.16" // here is the issue
        Event2.date = "12.11.16"  // "" "" "" ""
    }

我不明白为什么我可以使用自定义类事件中的完整日期变量,但不能使用日期变量。 谢谢你的帮助

最佳答案

您的日期实际上是一个计算属性,它只有一个getter 所以只能读不能写。

相比之下,您的 FullDate 是一个存储属性

计算属性 通常用于对其他类隐藏功能或以方便的方式公开隐藏的数据。

下面是 SomeClass 对象中的一些说明。

  • 存储的属性只是普通的旧属性
  • 计算属性getters,也可能是setters。一个很好的例子是 CGRectheightwidth,它们实际上来自 CGRect.size 但实现为 便利 setter/getter
  • property observers 是当stored properties 改变值时执行的函数。 didSetwillSet
  • getset 上的
  • access control 允许您创建只读或只写的存储属性关于访问。

class SomeClass {

    // just a variable
    var storedProperty : Int = 10

    // just a variable but the setter is hidden from other "files"
    private(set) var storedPropertyWithPartialAccessControl : Int = 0

    // only calculates when set
    var derivedProperty : Int = 0 {
        didSet {
            storedProperty = doStuffs(derivedProperty)
        }
    }

    // calculates every get and set
    var computedProperty : Int {
        get { // get is needed
            return doStuffs(storedProperty)
        }
        set(value) { // set is not needed, using only get gives you a read only property
            storedProperty = doReverseStuffs(value)
        }
    }

    // hidden functions that are used in the computed property
    private func doStuffs(value:Int) -> Int {
        return value * 10
    }

    private func doReverseStuffs(value:Int) -> Int {
        return value / 10
    }
}

因为 NSDateFormatter 效率很低,所以在 computed property 中使用它是非常糟糕的。每次获取都会创建一个。将浪费大量时间和精力,因为结果值可能在大多数时间都是相同的。

最佳实践:

  • 使用计算属性获取存储属性设置进行计算。
  • 使用单例存储NSDateFormatter

一个更好的方法:

class SomeEvent {

    // Store calculated results. 
    // This is private to make the class cleaner in use.
    private var storedDate : NSDate?

    private var storedFormattedDate : String = ""

    // get returns stored values without calculations
    // set updates both stored values after calculations
    var date : NSDate? {
        get {
            return storedDate
        }
        set(value) {
            storedFormattedDate = format(date: value)
            storedDate = value
        }
    }

    var formattedDate : String {
        get {
            return storedFormattedDate
        }
        set(value) {
            storedDate = readDateFrom(dateString: value)
            storedFormattedDate = format(date: storedDate)
        }
    }

    // hidden functions, again to make the class cleaner in use.
    private func format(date maybeDate:NSDate?) -> String {

        guard let date = maybeDate else {
            return ""
        }
        guard let dateFormatter = MyDateFormatter.shared().dateFormatter else {
            return ""
        }
        return dateFormatter.stringFromDate(date)

    }

    private func readDateFrom(dateString string:String) -> NSDate? {

        // get detector
        if let detector = MyDateFormatter.shared().dateReader {
            // results
            let matches = detector.matchesInString(string, options: [], range: NSRange(location: 0, length: string.characters.count))
            // first result
            if let match = matches.first, let date = match.date {
                return date
            }
        }

        // just format if there is no detector
        if let dateFormatter = MyDateFormatter.shared().dateFormatter {
            if let date = dateFormatter.dateFromString(string) {
                return date
            }
        }

        // everything failed
        return nil
    }
}

用于存储 NSDateFormatterNSDataDetector 的单例:

Google:Swift 单例

class MyDateFormatter {

    private static var privateShared : MyDateFormatter?

    var dateFormatter : NSDateFormatter?
    var dateReader : NSDataDetector?

    class func shared() -> MyDateFormatter {
        guard let uwShared = privateShared else {
            privateShared = MyDateFormatter()
            return privateShared!
        }
        return uwShared
    }

    class func destroy() {
        privateShared = nil
    }

    private init() {
        dateReader = try? NSDataDetector(types: NSTextCheckingType.Date.rawValue)
        dateFormatter = NSDateFormatter()
        dateFormatter!.dateFormat = "EEEE MMM dd"
    }
}

测试:

let event = SomeEvent()
event.formattedDate = "tomorrow"
event.formattedDate // "Friday Dec 04"
event.formattedDate = "25/02/2010"
event.formattedDate // "Thursday Feb 25"
event.formattedDate = "Sunday Mar 13"
event.formattedDate // "Sunday Mar 13"

关于swift - 如何解决此构建问题 - 无法分配给属性 : 'date' is a get only property,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34071428/

相关文章:

ios - 快速将数据推送到 UISplitViewController 的主视图 Controller 和详细 View Controller

ios - 使用 Swift 3 的核心数据指南

ios - 我试图选择一个随机字符串来填充各个标签,同时每次都删除所选的标签

swift - 为什么自动调整 UITextview 在这种情况下不起作用?

iOS 应用向右移动,无法查看完整表格

swift - 如何在 SwiftUI 中正确使用 NavigationLink

ios - Swift Firebase - 如何向 viewDidLoad 添加观察者,在 viewDidDisappear 中删除它,然后在 viewWillAppear 中再次读取它?

ios - 桥接 header 错误 - "xxx-Bridging-Header.h"文件在 SWIFT 中不存在

ios - 如何获取相机胶卷中或刚刚拍摄的照片的路径(iOS/Swift)?

ios - 具有不确定数量的 UIImageViews 的 UITableViewCell