无法从计算属性中为存储属性赋值

时间:2015-02-17 16:15:11

标签: swift

我创建了一个结构体,其中我有一个属性'_photo',在调用计算属性'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
        }
    }



}

3 个答案:

答案 0 :(得分:15)

对于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 { }上的{{1}}功能没有记录。

答案 1 :(得分:9)

Structs是值类型,它们是不可变的 这意味着你不能设置变量和变异自我 如果你需要改变struct,你必须使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
    }
}

答案 2 :(得分:4)

PhotoStructstruct,因此是值类型。对于价值类型, 只有明确标记为mutating的方法才能修改属性 self的{​​{1}},因此在计算属性中不可能。

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