【问题标题】:Cannot assign value to stored property from within computed property无法从计算属性中为存储的属性赋值
【发布时间】:2015-04-18 09:48:18
【问题描述】:

我创建了一个结构,其中我有一个属性“_photo”,当调用计算属性“照片”时,该属性被延迟分配。我不断收到错误

无法分配给“self”中的“_photo”

这里是代码。我用 Swift 1.1 (photo1) 和 swift 1.2 (photo2) 语法编写了计算方法。两者都给出与上述相同的编译时错误。

需要进行哪些更改才能修复该错误?

import UIKit

public struct PhotoStruct {
    var _photo:UIImage?
    var urlString:String?

    init(image:UIImage?, url:String?){
        self._photo = image
        self.urlString = url

    }

    init(url:String?){
        self.urlString = url
    }


    var photo1:UIImage? {

        if let theURL = self._photo {
            return self._photo
        }else{
            if let urlString = self.urlString{
                if let url = NSURL(string: urlString as String){
                    if let imageData :NSData = NSData(contentsOfURL: url){
                        if let image:UIImage = UIImage(data:imageData){

                            self._photo = image //** Cannot assign error is here**
                        }
                    }
                }
            }
            return self._photo
        }
    }

    var photo2:UIImage? {

        if let theURL = self._photo {
            return self._photo
        }else{
            if let  urlString = self.urlString,
                    url = NSURL(string: urlString as String),
                    imageData :NSData = NSData(contentsOfURL: url),
                    image:UIImage = UIImage(data:imageData){

                            self._photo = image //** Cannot assign error is here**
            }
            return self._photo
        }
    }



}

【问题讨论】:

    标签: swift


    【解决方案1】:

    至于struct,如果你想改变计算属性中的self属性,你必须将getter显式声明为mutating get { .. }

    public struct PhotoStruct {
        var _photo:UIImage?
        var urlString:String?
    
        init(image:UIImage?, url:String?){
            self._photo = image
            self.urlString = url
        }
    
        init(url:String?){
            self.urlString = url
        }
    
        var photo1:UIImage? {
            mutating get {
        //  ^^^^^^^^^^^^
                // you can set `self._photo = image` here
            }
        }
    
        var photo2:UIImage? {
            mutating get {
        //  ^^^^^^^^^^^^
                // you can set `self._photo = image` here
            }
        }
    }
    

    当然,结构本身必须是可变的:

    var pVar:PhotoStruct = PhotoStruct(image: nil, url: nil)
    pVar.photo1 // no problem
    let pLet:PhotoStruct = PhotoStruct(image: nil, url: nil)
    pLet.photo1 // < [!] error: immutable value of type 'PhotoStruct' only has mutating members named 'photo1'
    

    一个警告:

    据我所知,mutating get { } 功能在 the language reference 上没有记录。

    【讨论】:

    • 有趣,不知道“变异get”。
    【解决方案2】:

    Structs 是值类型,它们是不可变的。
    这意味着您不能设置变量和改变自我。
    如果你需要改变结构,你必须使mutating func

    public struct PhotoStruct {
        var _photo:UIImage?
        var urlString:String?
    
       mutating func loadPhoto() -> UIImage {
        .. Code here
       _photo = UIImage(data:imageData)
       // Here you mutate a struct, but it's ok because we make method as mutating
      }
    }
    

    在您的示例中,我将创建一个变异方法而不是属性

    mutating func photo () -> UIImage? {
    
        if let photo = self._photo {
            return photo
        } else {
            if let urlString = self.urlString,
            url = NSURL(string: urlString),
            imageData = NSData(contentsOfURL: url),
            image = UIImage(data:imageData) {
                self._photo = image
            }
            return self._photo
        }
    }
    

    【讨论】:

    【解决方案3】:

    PhotoStruct 是一个struct,因此是一个值类型。对于值类型, 只有明确标记为mutating 的方法才能修改属性 self,所以这在计算属性中是不可能的。

    如果您将PhotoStruct 更改为class,那么您的代码将编译 没有问题。

    【讨论】:

    • Swift 有这些愚蠢的细微差别,其中许多构造彼此相似,但仍然不同。
    • 奇怪的是,您不能从另一个属性的计算 get 中设置结构上的属性,但您可以从另一个属性的 didSet 设置所需的属性!我一生都无法弄清楚为什么这两者之间的行为会有所不同。
    猜你喜欢
    • 2017-06-11
    • 2023-03-19
    • 2022-06-23
    • 2021-05-04
    • 2014-08-02
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    相关资源
    最近更新 更多