3

I want to create instance variables dynamically at runtime, and I want to add these variables to a category. The number of the instance variables may change based on the configuration/properties file which I am using for defining them.

Any ideas??

8
  • 2
    How about having a NSMutableDictionary, and then you can set values for whatever keys you want? The dictionary holds everything and the key names would serve a function similar to ivars. Commented Dec 7, 2012 at 4:56
  • ok.. sorry for that, modified my question slightly Commented Dec 7, 2012 at 4:59
  • When you say "category", do you you mean the mechanism for adding methods to an existing class that you don't have access to? If so, Associative References that dasblinkenlight refers is probably the solution. If you're talking about adding dynamic values associated with one of your classes, a NSMutableDictionary probably makes sense. Commented Dec 7, 2012 at 5:02
  • Ofcourse, suppose I want to add additional functionality to an existing class.. Commented Dec 7, 2012 at 5:09
  • No, my question is whether you're adding it to one of your own classes (i.e. a class you can just add the single NSMutableDictionary as an instance variable), or whether you're using a category to add functionality to an existing class that you don't own (e.g. you wanted to add some Base64 encoding logic to the NSData class). You can't add the NSMutableDictionary to NSData (you have to use associative references), but you obviously can add the NSMutableDictionary to one of your own classes. You said "category", but that has a very specific meaning in Objective-C. Commented Dec 7, 2012 at 5:15

3 Answers 3

5

Use Associative References - this is tricky, but that is the mechanism invented specifically for your use case.

Here is an example from the link above: first, you define a reference and add it to your object using objc_setAssociatedObject; then you can retrieve the value back by calling objc_getAssociatedObject.

static char overviewKey;

NSArray *array = [[NSArray alloc] initWithObjects:@ "One", @"Two", @"Three", nil];
NSString *overview = [[NSString alloc] initWithFormat:@"%@", @"First three numbers"];

objc_setAssociatedObject (
    array,
    &overviewKey,
    overview,
    OBJC_ASSOCIATION_RETAIN
);
[overview release];

NSString *associatedObject = (NSString *) objc_getAssociatedObject (array, &overviewKey);
NSLog(@"associatedObject: %@", associatedObject);

objc_setAssociatedObject (
    array,
    &overviewKey,
    nil,
    OBJC_ASSOCIATION_ASSIGN
);
[array release];
Sign up to request clarification or add additional context in comments.

Comments

1

I'd be inclined to just use a NSMutableDictionary (see NSMutableDictionary Class Reference). Thus, you would have an ivar:

NSMutableDictionary *dictionary;

You'd then initialize it:

dictionary = [NSMutableDictionary dictionary];

You can then save values to it dynamically in code, e.g.:

dictionary[@"name"] = @"Rob";
dictionary[@"age"] = @29;

// etc.

Or, if you are reading from a file and don't know what the names of the keys are going to be, you can do this programmatically, e.g.:

NSString *key = ... // your app will read the name of the field from the text file
id value = ...      // your app will read the value of the field from the text file

dictionary[key] = value;  // this saves that value for that key in the dictionary

And if you're using an older version of Xcode (before 4.5), the syntax is:

[dictionary setObject:value forKey:key];

4 Comments

But for this way, I have to modify my code everytime to add keys and it tends more towards a static reference.
@AnilKumarReddy No, it doesn't have to be static. By definition, being a mutable dictionary, you can programmatically add whatever keys and values you want at run time. I just showed some static examples, but you can use syntax like dictionary[variableName] = variableValue;. It doesn't have to be static.
Is there any other way to make the solution for a category, I want to add new colors to the UIColor class at runtime based on the details in json/file. So ideally want to add ivars to use them.
@AnilKumarReddy You can (see dasblinkenlight's discussion), but in my opinion that is a bad use of dbl's solution. I'd wager that dbl would agree that this is not what his technique is designed to solve. This color information you've downloaded is an attribute of the file you've downloaded, not a change or extension of the intrinsic behavior of the UIColor class. Personally, I'd simply store the RGB (or HSB or however it's specified in the file) as an key-value pair in the same NSMutableDictionary that you're storing the rest of the stuff you've gotten from the file.
0

Depends on exactly what you want to do, the question is vague but if you want to have several objects or several integers or so on, arrays are the way to go. Say you have a plist with a list of 100 numbers. You can do something sort of like this:

NSArray * array = [NSArray arrayWithContentsOfFile:filePath];
// filePath is the path to the plist file with all of the numbers stored in it as an array

That will give you an array of NSNumbers, you can then turn that into an array of just ints if you want like this;

int intArray [[array count]];  
for (int i = 0; i < [array count]; i++) {
    intArray[i] = [((NSNumber *)[array objectAtIndex:i]) intValue];
}

Whenever you want to get an integer from a certain position, lets say you want to look at the 5th integer, you would do this:

int myNewInt = intArray[4];
// intArray[0] is the first position so [4] would be the fifth

Just look into using a plist for pulling data, it will them be really easy to create arrays of custom objects or variables in your code by parsing the plist.

Comments

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.