cocoacocoa-bindingskey-value-observingnsarraycontrollerkey-value-coding

Cocoa binding to single object from an array


I previously posted this question as a comment on a related thread thinking it was simple. That thread is here:

Cocoa binding to a particular item in an array controller

The questions relates to (and I'll more fully describe it here) a game I'm building to try and learn objective-c and cocoa. Its good enough to think of it like texas hold-em poker. One server holds the game information and manages input from a variable number of clients (always more than one). Through cocoa bindings, it displays to each player the public information of the game which is stored in an array on the server using an array controller in IB. Think of the five cards on the table being stored in an NSArray on the server and bound to the content field of an NSArrayController for each client.

This part works fine, like a charm. However, each player has two cards that he needs to keep private. Each client should display a different card depending on what was dealt to that particular player. (Because what is really happening is I'm binding to an array of player objects

NSArray * thePlayers, 

imagine all the cards being stored on the same array). So my question is, how do I set up bindings to a single object out of the array controller (or do I need some other controller)? That is, how to I bind to one player of thePlayers array?'


Solution

  • However, each player has two cards that he needs to keep private. Each client should display a different card depending on what was dealt to that particular player. (Because what is really happening is I'm binding to an array of player objects …

    The client knows which player it's representing, right? Not by index—it should have a direct reference to the Player object for the player sitting at its keyboard. Something like MyPlayer *userPlayer;. This is in addition to the dealer object holding an array of all the players, including that one.

    Once you have it lain out that way, with the client controller having a property whose value is the user's Player object, the binding becomes simple: You'll bind the card views directly to card A and card B of the userPlayer property of the client controller. (This is essentially what Chuck already suggested in his answer, and what I suggested in my comment on your answer on that other question.)

    imagine all the cards being stored on the same array).

    Why would I want to imagine that? Why don't the players own their own cards separately?

    OK, so the dealer should own all the cards (that is, the deck). It should co-own those also held by a player. The players don't access their cards through the dealer; each player should directly hold his or her cards.

    It sounds like you made the same mistake with cards as with players: Thinking that one object can/should know another through an array by index. You can't—certainly not if you want to use that knowledge with Bindings—and shouldn't. The one object needs to know the other directly. This is not only the correct solution, it's the correct way for objects to know each other. Any array-index-based reference would be more complex for no benefit.