Given your class:
  //  Popup.h
//  TestPopup

#import <Cocoa/Cocoa.h>
@interface Popup : NSObject
{
   NSArray *popupArray;
   NSString *selectedGame;
}
@property (readwrite, copy) NSArray *popupArray;
@property (readwrite, copy) NSString *selectedGame;
@end
   
   
  To start with, in my opinion you have a broken model from a MVC perspective.  
Having a class called "Popup" in the Model subsystem is a dead give away.  The 
Model should not know or care how information is presented to users.  The 
Model's only concern should be storing and manipulating data that is valuable 
and useful even if there is no particular user interface at all.  The Model 
subsystem should probably not be concerned with the user's current selection 
either in my opinion, but others might disagree.
   
  I am guessing that you are trying to implement a Model that internally 
manages, controls, implements, dare I say models, some games.  One thing the 
Model knows about is which games are available.  Perhaps the available games 
are loaded from a data file or stored in a database or obtained over a network. 
 These are all proper roles for a Model.  
   
  If the set of games available is static and constant and will most likely 
never change, there is no need for a specialized Model object to store those 
games.  The Model object might just be
  NSSet   availableGames = [[NSSet alloc] iniWithObjects::@"C9", @"F11", nil]];
   
  If more complex logic is needed to determine the set of games available, 
there might be a class like the following:
   
  @interface GameManager : NSObject
  {
   NSSet        *availableGames;
}
@property (readonly, copy) NSSet *availableGameNames;
@end
   
  The availableGames property should be declared readonly in the interface and 
re-declared readwrite in the implementation of the class.  If the job of 
GameManager is to encapsulate the set of available games, no other object 
should be setting that property.
   
  So what about selection?  As it happens, NSArrayController is more than able 
to store information about the user's current selection.  NSArrayController is 
(as you might imagine) properly part of the Controller subsystem in MVC.  The 
job of the Controller is to mediate between the user interface, View, and the 
Model. An instance of NSArrayController is a good choice on this occasion.   
The NSArrayController instance will also take care of rearranging, sorting, and 
filtering Model data for presentation to the user, but that is another 
subject...
   
  In Interface Builder, instantiate an instance of NSArrayController.  Bind the 
content of the NSArrayController to the availableGames property of a handy 
GameManager instance.  You will need to decide where in your application the 
GameManager instance will be created and what the key path to that instance 
will be.  The key path might be through the nib file's owner for example.  You 
will also probably want to limit the NSArrayController to single selection, no 
empty selection, no add or remove, etc.
   
  Now that you have an NSArrayController instance that hides the underlying 
Model storage for a conceptual set of game names from which a user might 
select, you can use any View subsystem interface construct you want to present 
the game names.  You might want a table view or a popup button or a collection 
view or a custom control.  It doesn't matter and shouldn't.  To hammer on the 
point, the View should have no knowledge of the Model other than perhaps some 
property key names.  That way, you are free to change either the Model 
implementation or the View implementation without affecting the other.
   
  I can hear you asking, if my Model doesn’t know the user’s selected game, how 
can the Model start the selected game or configure the selected game or 
whatever it has to do?
   
  Everything depends on what you want to do with the selected game.  If the 
goal is to display a detail View that enables the user to configure the 
selected game before starting it, there might be more Controller layer objects 
that have bindings to the available games array controller’s selectedObject.  
That is a common Masterß>Detail kind of user interface.  This brings up an 
interesting question: why are we only storing available game NAMES?  Why not 
use the Model to store available game Objects that among other things know 
their name ?
   
  @interface Game : NSObject
  {
   NSString       *name;
     int                  numberOfPlayers;
     float               difficulty;
}
@property (readonly, copy) NSString *name;
  @property (readwrite) int  numberOfPlayers;
  @property (readwrite) float  difficulty;
   
  - (NSString *)description;  // implement to return [self name];
  
@end
   
   
  @interface GameManager : NSObject
  {
   NSSet        *availableGames;
}
@property (readonly, copy) NSSet *availableGames;
@end
   
   
  @implementation GameManager 
  {
   NSSet        *availableGameNames;
}
@synthesize (readwrite, copy) NSSet *availableGames;
   
  - (id)init
  {
     self = [super init];
      if(nil != self)
      {
         [self setAvailableGames:[[[NSSet alloc] initWithObjects:[C9Game 
defualtGame], [F11Game defaultGame, nil] autorelease];
     }
     Return self;
   }
  
@end
   
  Guess what?  We just changed the Model, and the NSArrayController and 
whatever View you used still work without change!  Why is that?  Because when 
the user interface object, let’s call it a popup button, tries to display 
information about the arranged objects in an array controller, the –description 
method is used to get the information, in this case the game’s name.
   
  However, we can now implement a more full featured Masterß>Detail type View 
because the NSArrayController’s selectedObject will now be an instance of class 
Game.  Notice how all of this worked thanks to dynamic typing.  The 
NSArrayController didn’t need to know the type of the content objects.  The 
hypothetical popup button didn’t need to know the type of the array 
controller’s arranged objects.  We were able to change the Model implementation 
without repercussion because of dynamic typing which conceals specific type 
information from the Controller and View subsystems.
   
  So, the hypothetical Game configuration detail user interface can bind a text 
field to the available games array controller’s selectedObject.numberOfPlayers. 
 The text field could have an associated number formatter that limits the user 
input to reasonable values like numbers between 1 and 5000.
   
  So, the Model still doesn’t know about the user’s game selection.  How is a 
game started ?
   
  Bind a button’s target to the available game controller’s selected object.  
Set the button’s action to –startGame:.  Implement a –startGame: method in the 
Game class.  When the buton is pressed, the selected Game instance will receive 
a startGame: message.
   
  THIS WAS ALL TYPED IN AN EMAIL PROGRAM.
   


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to