Make variable names variables (Objective-c) - objective-c

I'd like to do something like this:
.h
LocalRoom* zone1;
LocalRoom* zone2;
LocalRoom* zone3;
LocalRoom* zone4;
etc....
.m
NSString *number = 1;
NSString *variable = [NSString stringWithFormat: #"zone%#", number]
[[variable variableValue] broadcastChatMessage:redStringPrefix fromUser:#"server"];
emulating:
[zone1 broadcastChatMessage:redStringPrefix fromUser:#"server"];
How do I do this? Is it possible?

Given names like “zone1”, “zone2”, etc., I would make an array rather than a dictionary. Either way, these should not be separate variables.

#property(strong) NSMutableDictionary *zones;
-(id)init {
....
_zones = [[NSMutableDictionary alloc] init];
....
}
aZone = [_zones objectForKey: [NSString stringWithFormat:#"zone%d", someZoneNumber]];
... etc ...

You can do something similar using Key-Value Coding. You would write
[[self valueForKey:variable] broadcastChatMessage:redStringPrefix fromUser:#"server"];
rather than
[[variable variableValue] broadcastChatMessage:redStringPrefix fromUser:#"server"];
This would of course require that zone1, zone2, etc. are instance variables (or properties) on self.

Related

How to add new array element from another method in Objective-c?

I have some array( #private NSArray employees []; ) and method , which take string parameter( name of employees) and put this parameter in array. How I can do this with Objective-c?
You could do the following,
Create a property,
#property (nonatomic) NSMutableArray *array;
Initialise the array in your init method or somewhere else appropriate,
self.array = [[NSMutableArray alloc] init];
Your method could look something like this,
- (void)addEmployeeName:(NSString *)employeeName {
[self.array addObject:employeeName];
}
You can create a class Employee and use a type with your array.
For example:
NSArray<Employee*> * employees = [[NSArray alloc] init];
At this point, your method will be:
-(Employee *)createEmployee:(NSString *)name{
Employee *myEmpl = [[Employee alloc]init];
[myEmpl setName:name];
return myEmpl;
}
and you can add the object (of type Employee) in your array in this way:
[employees addObject:[self createEmployee]];
the same thing is possibile with an object of type NSString instead of Employee.
You can also avoid defining the type in your NSArray because Objective-C use the type inference

Self assignment for NSString category

I want to self assign an adjusted nsstring via category.
The example is a trim function:
I do not want that way:
NSString *theTempString = [theExampleString xTrim];
// ... go on doing stuff with theTempString
I want it this way:
[theExampleString xTrim];
// ... go on doing stuff with theExmapleString
The category looks like this:
- (void)xTrim
{
self = [self stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]];
}
The error that an assignment outside init is not possible - I understand that.
But now I'm interested in it, of course I can write an custom init methode, but is there no way around it like the one above???
Greetings and thanks,
matthias
You don't need to create a new NSString, the method already does that for you:
- (NSString *)xTrim
{
return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}
NSString is immutable so you need to assign it:
yourString = [yourString xTrim];
You cannot do that in a category on NSString, because NSString manages immutable strings, which means that the string can not be changed after it has been created.
You could implement it as category on NSMutableString:
- (void)xTrim
{
NSString *trimmed = [self stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceCharacterSet]];
[self setString:trimmed]; // replaces the characters of "self" with those of "trimmed".
}
And if your question is: Can I write a method xTrim such that
[theExampleString xTrim]
replaces the receiver theExampleString with a new instance: No, that is not possible.

Have trouble appending to an NSMutableString

#interface MainView : UIView {
NSMutableString *mutableString;
}
#property (nonatomic, retain) NSMutableString *mutableString;
#end
#implementation MainView
#synthesize mutableString;
-(void) InitFunc {
self.mutableString=[[NSMutableString alloc] init];
}
-(void) AppendFunc:(*NString) alpha {
[self.mutableString stringByAppendingString:#"hello"];
NSLog(#"the appended String is: %#",self.mutableString);
int len=[self.mutableString length];
}
Hey Everyone,
i just want to know where I am doing wrong ??? . I tried this code but "mutableString" does not append any value (as value of "len"comes '0' and NSLog doesnt print any value for "mutableString"), though i ve searched on net for the solution, people implemented in the same fashion yet i dont know why my code isnt working.
Thanks in Advance
MGD
stringByAppendingString: creates new string. Use appendString: instead:
[mutableString appendString:#"hello"]
1) Your method names violate the naming conventions: use lower case letters to start with.
2) stringByAppendingString returns a new string as a result and doesn't modify your original. You should use [self.mutableString appendString:#"hello"]; instead.
3) Your init method is leaking. You should use mutableString = [[NSMutableString alloc] init]; and not use the dot syntax, as it will be retained otherwise (and a release would be missing).
Oh God, what a mess. The stringByAppendingString does not change the string, it creates and returns a new one:
// Sets str2 to “hello, world”, does not change str1.
NSMutableString *str1 = [NSMutableString stringWithString:#"hello, "];
NSString *str2 = [str1 stringByAppendingString:#"world"];
If you want to change the mutable string itself, use the appendString method:
// Does not return anything, changes str1 in place.
[str1 appendString:#"world"];
Also, this is a leak:
self.mutableString = [[NSMutableString alloc] init];
This is best written as:
mutableString = [[NSMutableString alloc] init];
…because using accessors in init and dealloc is not the best idea.

Objective-c: Dynamic Class Names

I'm not sure if I worded the subject correctly. I am looping through an array, within each loop I am trying to instantiate a class, but I want to dynamically create the name. Like so:
int i = 0;
for(NSString* thisdatarow in filedata) {
i++;
NSString* thisad = [NSString stringWithFormat:#"ad%d", i];
NSLog(#"%#", thisad);
AdData* thisad = [AdData new];
}
In the example above I want AdData* thisad... to be named dynamically - "ad1", "ad2", "ad3"...and so on. I get a conflicting type error.
This code also generated an error:
int i = 0;
for(NSString* thisdatarow in filedata) {
i++;
AdData* [NSString stringWithFormat:#"ad%d", i] = [AdData new];
}
Is there a way to do this?
You can't do that in Objective-C.
Use a NSString to AdData map--it'll do basically the same thing!
**edit: To clarify, use an:
NSMutableDictionary *dict;
with keys that are NSString* objects containing the ad names, and values that are the AdData* objects.
i.e.
[dict setValue:ad1 forKey:#"ad1"];
to set the values, and
[dict valueForKey:#"ad1"];
to get the values. (ignore the obvious memory leaks there with the strings...)
This isn't possible. While Objective-C is very dynamic, it's not that dynamic.
The suggested way to do this would be to create your instances and put them into an array, not assigning them to explicitly named variables.
You can then refer to them individually using their index in the array.
Something like this:
NSMutableArray *ads = [NSMutableArray array];
for(NSString* thisdatarow in filedata) {
AdData* thisad = [[[AdData alloc] init] autorelease];
[ads addObject:thisad];
}
// get third ad:
AdData *ad = [ads objectAtIndex:2];
Alternatively you could create an NSDictionary, if you really want to refer to them by a name, like this:
NSMutableDictionary *ads = [NSMutableDictionary dictionary];
int i = 0;
for(NSString* thisdatarow in filedata) {
i++;
AdData* thisad = [[[AdData alloc] init] autorelease];
NSString *keyName = [NSString stringWithFormat:#"ad%d", i];
[ads setObject:thisad forKey:keyName];
}
// get third ad
AdData *ad = [ads objectForKey:#"ad2"];
Cant be done Without using a C array, which would look like this:
AdData **ad = malloc(sizeof(AdData) * numberOfAds);
ad[1] = [AdData new];
// etc.
if (ad)
free(ad);
But I don't know how that would work because of how Objective-C classes are stored....
Local variable names are a purely compile-time concept. So you cannot do anything "dynamic" (i.e. at runtime) with it. The compiler is free to rename the variables and add or remove variables as it sees fit.
If you think about it, what is the point of dynamically manipulating local variable names? In order to use the dynamically-named variable again, you must either 1) explicitly refer to the variable name, in which case you have hard-coded the name (not so dynamic), or 2) dynamically construct the name again. If it's (1), then there is only a fixed set of variable names, so dynamic-ness is unnecessary. If it's (2), you're missing the point of local variable names (the whole point of which is so they can be referred to explicitly).

Is it necessary to assign a string to a variable before comparing it to another?

I want to compare the value of an NSString to the string "Wrong". Here is my code:
NSString *wrongTxt = [[NSString alloc] initWithFormat:#"Wrong"];
if( [statusString isEqualToString:wrongTxt] ){
doSomething;
}
Do I really have to create an NSString for "Wrong"?
Also, can I compare the value of a UILabel's text to a string without assigning the label value to a string?
Do I really have to create an NSString for "Wrong"?
No, why not just do:
if([statusString isEqualToString:#"Wrong"]){
//doSomething;
}
Using #"" simply creates a string literal, which is a valid NSString.
Also, can I compare the value of a UILabel.text to a string without assigning the label value to a string?
Yes, you can do something like:
UILabel *label = ...;
if([someString isEqualToString:label.text]) {
// Do stuff here
}
if ([statusString isEqualToString:#"Wrong"]) {
// do something
}
Brian, also worth throwing in here - the others are of course correct that you don't need to declare a string variable. However, next time you want to declare a string you don't need to do the following:
NSString *myString = [[NSString alloc] initWithFormat:#"SomeText"];
Although the above does work, it provides a retained NSString variable which you will then need to explicitly release after you've finished using it.
Next time you want a string variable you can use the "#" symbol in a much more convenient way:
NSString *myString = #"SomeText";
This will be autoreleased when you've finished with it so you'll avoid memory leaks too...
Hope that helps!
You can also use the NSString class methods which will also create an autoreleased instance and have more options like string formatting:
NSString *myString = [NSString stringWithString:#"abc"];
NSString *myString = [NSString stringWithFormat:#"abc %d efg", 42];