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

时间:2017-07-28 23:52:15

标签: ios swift swift3

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

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的更好方法?

2 个答案:

答案 0 :(得分:3)

这是因为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)") 

答案 1 :(得分:0)

$data = [ 'company_name' => $company_name, 'login_email' => $login_email, 'password' => $plain_password ]; Mail::send('emails.comp_ver_emails', $data, function($message) use ($data){ $message->to($data['login_email']); $message->subject('Please verify your email address to get started'); }); return redirect()->back()->with('success','Thank you'); 返回不同值的原因是因为allProductsInCartPass by Value的概念,它与变量静态或全局无关。 / p>

Pass by Reference是一个对象。所有对象都称为Product。这意味着对象的值指向内存中的某个位置,并且每当内存中该位置的值发生更改时,该值都会在指向内存中该位置的其他位置更改。

由于Pass by Reference存储了一个allProductsInCart数组,因此它存储了一个Product数组,这意味着,每当您更改对象的值时,您正在更改的值无论它存储在内存中的何处。

编辑: 如果您希望它为Objects,则必须将数组转换为基本数据类型。例如:

pass by value会阻止值被更改。

您的代码将如下所示:

var productName = [String]()

然后当你打电话

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

它将打印Costco。

看看What's the difference between passing by reference vs. passing by value?  有关let newProduct = Product() newProduct.name = "Costco" Cart.instance.productName.append(newProduct.name!) newProduct.name = "test2" print("Value is \(Cart.instance.productName[0])") pass by value

的详细信息