views:

59

answers:

2

I have a character model class which has this structure:

@interface CharacterModel : NSObject 
{
    // parent of this character
    CharacterModel *parentChar;

    // basic details
    NSString *fname, *sname, *nick;
    NSString *char_type; // categories of characters: dwarf, etc

    // health
    int health;

    // cash
    double cash;
    double graft;

    // flags
    bool is_cop, is_player, is_ai, is_playable;

    // Skills
    int skill_speed;
    int skill_stamina;
    int skill_aggr;
    int skill_another;
    int skill_somethingelse;
    // Total = 100

    // Hidden RPG skills
    int corruption;
    int greed;

    // Rep skills
    int reputation;

    // Misc. flags
    int active, picked, is_locked;
}

The problem are 2 things.

1) I would need to re-write this structure in the @property (nonotomic)... part of the .h file, and I would need to do it again for @synthesize part of the .m file

Is there a way to reduce the need to re-write stuff; can I put all this in a struct or something and then just @synthesize that?

2) The constructor will have a stupidly long function name.

I really, really do not want to be writing a constructor that has hundreds of variables/fields.

ie:

-(id)initCharacter:(NSString *)name, and every other class variable mentioned above ...

Is there are a way around this?

I was thinking of doing a NSMutableDictionary, but you would STILL need to write a constructor with every field you want somewhere.

Any help on this would be great.

Thanks

A: 

If you can use the modern Objective-C runtime (available on the iPhone and for 64 bit OS X programs) you will have to write the property definitions twice. Just write the @property and the @synthesize parts, the instance variables will be created automatically. If you need to support the old runtime you just have to write it three times, there is nothing you can do about it.

To the constructor you probably should not pass values for every property. Initialize them to some sensible default values. Note that you don’t have to do anything if the default value is 0, 0.0, nil or NULL - alloc makes sure that all ivars are initialized to zero.

If you want to set all the properties from a NSDictionary you can use key-value-coding to set them instead of doing this manually:

for (NSString *key in dictionary) {
    id value = [dictionary objectForKey: key];
    [self setValue: value forKey: key];
}
Sven
If I put a dictionary, I would still need to write a constructor with all the vars regardless of whether they are initialize to zero or not -- unless I've mis-understood what you mean.
zardon
+3  A: 

I really think you should take your design one step further. It is very inflexible to have explicitly defined all the skills and flags like that. Consider creating new classes called:

  • Skill
  • Attribute
  • Flag

Your character class will then have:

NSMutableArray* skills;
NSMutableArray* attributes;
NSMUtableArray* flags;

and obviously getters/setters and add/remove methods for each.

Not only will it make your class look neater but it will also save you a lot of typing.

willcodejavaforfood
I will certainly try your idea. When you say new classes do you mean having array's in the character class, or in separate classes?
zardon
If I seperate this into 2 classes -- wouldn't I still need to keep a reference in each of these classes to its relating (parent) `character`?
zardon
Your character class could have arrays holding skill objects, attribute objects, flag objects. Makes sense? :)
willcodejavaforfood
Yes, it does. Thanks for your help. I'm going to try this right now. Thanks.
zardon
No problem, if you like my answer (or any other) please don't forget to upvote it :)
willcodejavaforfood
I do not think NSMutableArray's are right for this because all you're doing is setting an object; it does not have any value associated with it; therefore I'm going to try and use NSDictionary. However, you still have some repetitive typing of key names and their values.
zardon
A dictionary would work as well :)
willcodejavaforfood
I really find NSDictionaries hard to understand; its really confusing where I am in the structure ` self.credentials = [[NSMutableDictionary alloc] initWithObjectsAndKeys:nil, @"name", nil];` What happens if it needs sub-dictionaries, it gets really confusing.
zardon
If I set a value for it, I can't seem to get it back `[self.credentials setValue:@"Name" forKey:@"name"]; NSEnumerator * enumerator = [self.credentials objectEnumerator]; id element; while(element = [enumerator nextObject]) { // Do your thing with the object. NSLog( @"%@", element ); }`
zardon
search for examples using NSDictionary http://stackoverflow.com/questions/3822524/tomcat-serving-static-content
willcodejavaforfood
Okay, thanks. I'll see if I can look up some tutorials on it too.
zardon
A colleague has mentioned using a Strategy design pattern and/or factory design pattern to help with this problem. I've not done design patterns before; but will look into this further.
zardon
I guess the instances of Skill, Attribute, Flag would be used in a manner that fits with the Strategy pattern. Especially if you have a Skill activeSkill property. But possibly your game wont work in a way that you choose one active skill like diablo :)
willcodejavaforfood