繁体   English   中英

不应该从另一个VC更新Struct Gobal

[英]Struct Gobal is being updated from another VC when it shouldn't be

我们正在创建一个全球结构,将我们的产品存储在购物车中。 这是创建它的代码

class Cart : NSObject {
    var allProductsInCart = [Product]()

    class var sharedCart: Cart {
        struct Static {
            static let instance = Cart()
        }
        return Static.instance
    }
}

在一个单独的视图控制器(称为ProductVC)中,我们正在创建Product的实例。 我们将产品添加到上面列出的数组中,将allProductsInCart这样,然后更改值:

let newProduct = Product()
newProduct.name = "Costco"
Cart.sharedCart.allProductsInCart.append(newProduct)
newProduct.name = "test2"
print ("value is: \(Cart.sharedCart.allProductsInCart[0].name)") //It prints "test2" not "Costco" 

在ProductVC中修改产品的单独实例时,其结构也会更改。 它绝对是产品的单独实例,因为它具有不同的变量名,如上所示。

它应该仍然打印Costco,因为ProductVC中的Product实例在添加到结构后已被修改,而我们想在结构中打印该实例。 对? 还是我有什么问题?

这是正常行为吗? 是否有发生这种情况的原因? 是否应该有更好的方法来创建全局变量,还是有更好的方法来创建我们可以在任何视图控制器中访问的sharedCart?

发生这种情况是因为newProduct是引用类型(由类定义),因此当您更改名称时,它只会更改同一引用的名称。 此时,购物车中只有一种产品,而不是两种。 作为参考,在Swift中定义单例的最简单方法是

class Cart {
    static let shared = Cart()

    var products = [Product]()
}

因此,仅遵循您的示例:

let newProduct1 = Product()
newProduct1.name = "Costco"

Cart.sharedCart.products.append(newProduct1)

let newProduct2 = Product()  // a new product
newProduct2.name = "test2"
// I assume you will want to add this product as well
Cart.shared.products.append(newProduct2)

//This will print "Costco" 
print ("value is: \(Cart.sharedCart.products[0].name)") 

allProductsInCart返回不同值的原因是由于一个称为“ Pass by Value Pass by Reference与“ Pass by Reference Pass by Value ”的概念,这与静态或全局变量无关。

Product是一个对象。 所有对象都称为“ Pass by Reference 这意味着对象的值指向内存中的某个位置,并且只要更改内存中该位置上的该值,该值就会在指向内存中该位置的其他所有位置处更改。

由于allProductsInCart存储了一个Product数组,因此它存储了一个Objects数组,这意味着,无论何时更改对象的值,都将更改存储在内存中的值。

编辑:如果希望pass by value它,则必须将数组转换为原始数据类型。 例如:

var productName = [String]()将防止更改值。

您的代码将如下所示:

class Cart : NSObject {
    var productName = [String]()
    static let instance = Cart()
}

那你打电话的时候

let newProduct = Product()
newProduct.name = "Costco"
Cart.instance.productName.append(newProduct.name!)
newProduct.name = "test2"
print("Value is \(Cart.instance.productName[0])")

它将打印Costco。

看一下按引用传递与按值传递有什么区别? 有关pass by value pass by referencepass by reference pass by value更多信息

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM