2

For some reason, when assigning an object of Observable to a variable and then changing it - the view won't update. but If I access it by its index directly - it will:

Won't work:

var people = self.mypeople.people[0]
people.name = 'test'

Does work:

self.mypeople.people[0].name = 'test'

My guess is something about references, but I'm not sure :(

Example code:

//: A UIKit based Playground for presenting user interface

import SwiftUI
import PlaygroundSupport
import Combine

struct Person: Identifiable{
    var id: Int
    var name: String

    init(id: Int, name: String){
        self.id = id
        self.name = name
    }

}

class People: ObservableObject{
    @Published var people: [Person]

    init(){
        self.people = [
            Person(id: 1, name:"Javier"),
            Person(id: 2, name:"Juan"),
            Person(id: 3, name:"Pedro"),
            Person(id: 4, name:"Luis")]
    }

}

struct ContentView: View {
    @ObservedObject var mypeople: People = People()

    var body: some View {
        VStack{
            ForEach(mypeople.people){ person in
                Text("\(person.name)")
            }
            Button(action: {
                var people = self.mypeople.people[0]
                // this howver works:
                // self.mypeople.people[0].name = 'Test'
                people.name="Jaime2"
            }) {
                Text("Change name")
            }
        }
    }
}


PlaygroundPage.current.liveView = UIHostingController(rootView: ContentView())

1 Answer 1

2

Your guess is correct!!

People objet is reference type and Person object is value type.

From here I can check type of object by this code:

func isReferenceType(toTest: Any) -> Bool {
    return type(of: toTest) is AnyObject
}

isReferenceType(toTest: Person(id: 1, name:"Javier")) //false
isReferenceType(toTest: People()) //true

So that when you get person by this line var people = self.mypeople.people[0], it just get and create new Person (address of this object is difference with self.mypeople.people[0] object), so in this case you expect change your data in array, you must set self.mypeople.people[0] = people after change people.name

HERE for more details about Reference Type and Value Type

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much! I was unable to find this information when searching.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.