简体   繁体   中英

Array of entity does not mutate in swift?

User Entity Model-

class UserEntity: NSObject {

    var isAlreadyUser:Bool

    init(isAlerdy:Bool){
        isAlreadyUser = isAlerdy
    }

}

App Delegate / Global Array

let new = ["F","E","D","C","B","A"]
        for obj in new{
            arrUser.append(UserEntity(isAlerdy: false))
        }

VIEW CONTROLLER

   let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate

    let home = Array(appDelegate.arrUser)

    home[0].isAlreadyUser = true

    print(appDelegate.arrUser[0].isAlreadyUser)

After I edit the local home array and update isAlreadyUser to true from false. This also changes in global array. Even I am mutating any making a copy of global array it still changes it i both the array.

I think some thing is wrong with entity. It is strong and not changing according to local scope of array.

Help me out.

EDIT:

let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        var areAlreadyUsers:[UserEntity] = []

        areAlreadyUsers = Array(appDelegate.arrUser)

        areAlreadyUsers[0].isAlreadyUser = true

        print(appDelegate.arrUser[0].isAlreadyUser)

Still no help. My global array is still changing.

If you were to make the UserEntity into a struct, you would not have the problem. Does it need to be an NSObject if not try using struct instead of class. This way you get copy on write behavior.

Problem:

The elements of the array are referenceType hence only the pointers to the objects will be copied. Hence modifying them will reflect in both the places.

Solution:

  1. Copy each item contained in the array.

    you can do some thing like, let localArray = globalArray.map { $0.copy() } . Please note that it is important your object should implement any of the copy methods such as copyWithZone .

  2. Use a value type such as struct instead of class .

The point is that arrUser and home just contain pointers to the same UserEntity objects, which are unique (not copied). So what you do you just change a value of a UserEntity property and it will obviously be reflected everywhere.

What you want to do is to rethink your app architecture, why would you mutate this value at all? For instance, you can create an array

var areAlreadyUsers:[UserEntity] = []

and just save there pointers to users that you would give true value. This way this information isn't saved anywhere.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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