3

say I have an array of Person structs like this:

struct Person {
    var name: String
}

var persons = [Person(name: "A"), Person(name: "B"), Person(name: "C")]

let publisher = CurrentValueSubject<[Person], Never>(persons)

// subscribe to changes to the array
let subscription: AnyCancellable = publisher.sink { (persons) in
    print("The array has changed")
}

var currentPersons = publisher.value
currentPersons[0].name = "Changed"
publisher.send(currentPersons)

This works. It publishes every time anything in the array changes or if something is deleted or added.

But what if I wanted to additionally be able to subscribe to only one element in the array? Can I do that? I simply can't figure it out.

3
  • Make Person observable, by exposing its properties as CurrentValueSubjects Commented Sep 14, 2019 at 23:22
  • I tried that but it didn't quite work. I always end up having multiple copies of the persons array, instead of tracking one single instance of it Commented Sep 15, 2019 at 8:37
  • Wrap your array into a Contacts object or whatever, and make it the unique owner of the array. Commented Sep 15, 2019 at 9:20

1 Answer 1

3

Being referred to in an array does not magically place an object under observation. If you want to observe an object, you must observe that object, itself. Keeping such observations coordinated with the contents of some array is quite tricky, as you will need to start observing a new object when it is added and stop observing it when it is removed.

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

2 Comments

That's what I feared. I just hoped there was an easy way to do it. I've played around with it for four entire days without making it work. At this point, I consider going back to using classes as data models (I switched because I read structs are better for this). Tracking changes is more work inside the class but it just seems way easier to do these things without ending up with multiple copies of your data that are out-of-sync.
Well it’s not like this is a new problem. People have been doing this with KVO for years. See github.com/MaxGabriel/NSArrayKVO for a typical approach. You could adapt that to Combine (which after all can use KVO).

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.