How to access a property/variable using a String holding its name - objective-c

If I had two variables in Objective C like this where one holds the name of the other as a string
NSInteger result = 4;
NSString * theName = #"result";
How would I best access the first variable using the string instead of a reference to the variable? For instance if I had a lot of variables and would generate the name of the one I need by code I'd need a way to get to the variable using that string.

Though not directly answering your question, it's possible to access properties (or ivars) of an object by
[object setValue:#"value" forKey:theName]
Similarly, the getter is [object valueForKey:theName] (thanks kevboh!)

That's not possible in objective-c. Variable names cannot be synthesised by name. The variable name itself doesn't mean anything when running your code, the compiler converts it into a memory address. The name is just a way for the programmer to make writing and reading code easier.
Depends on your exact situation but you probably should be using an NSArray or NSDictionary.

Related

What is the actual difference between an 'object' and a 'variable' in Objective-C?

I would like to ask a question, about an 'Object' and 'variable' in Objective-C. As we know, we can take many variables to store data of an object, but first we have to create an object with allocation. We have to give a memory location for our object in RAM using 'alloc' keyword. I think object can't store data because, an object is a noun, like a person. So, to store a data we need to use a variable. In C or C++ we use a variable of any primitive data type for data storage purpose. In Objective-C we use predefined classes like NSString.
So, can I use a variable with my NSString class type or I will use only an object with class type object.
There are two problems for me.
NSString *xyz = [[NSString alloc] init]; // can anyone tell me what should be 'xyz' in here a 'variable' or an 'object'?
if 'xyz' is an object in here. So, firstly I have to create it. But somewhere I have seen like....
NSString *xyz = #"welcome"; // according to me, here we are not allocating memory for 'xyz'. Why?
What is the difference between both statements? Can you please tell me?
Objects are instances of classes. (And that's all there is. Nothing else needs saying).
Variables are global and static variables (having unlimited life times) and automatic variables (variables existing while a function is executing, or while a new scope in a function is entered), and disappearing when the scope ends or the function returns.
In Objective-C, objects can never be variables. Pointers to objects can be variables, but objects can't. Values that are part of an object are often called "instance variables", but that is not the same as a variable.
In other languages, like C++, objects can be variables. The question "what is the difference between objects and variables" doesn't really make sense. It's like asking "what's the difference between alcohol and a cow". They are different categories of things.
#"MyString" is a shortcut; the compiler will create an object for you and give you a pointer to that object.

Modify strings with reflection

I was reading this question/answers, which basically showed an interesting behaviour in Java and strings, and two questions came up in my mind:
Are Objective-C/Swift String s behave the same? I mean if I have for example two variables which stores the same literal "someString", internally, will they refer to one "someString" object? I didn't find anything about it in the documentation.
If the answer to my previous question is yes, then is it possible to change same string literals the way like in Java?
Not all NSString literals (#"string literal") share the same storage due to compilation units.
NSString literals can not be changed in the program code, they are compiled into readonly segments.
NSString variables, that is that are created at runtime, only are shared by assignment.
NSString instances are immutable and can not be changed after creation.
NSMutableString instances can be modified and all variables pointing to such an instance point to the same change.
Swift is slightly different, as #Grimxn points out, Swift String is not a class and immutability is determined by the declaration syntax: let or var.

The asterisk in Objective-C object instance declarations: by the Object or by the instance? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What's your preferred pointer declaration style, and why?
In C, why is the asterisk before the variable name, rather than after the type?
What makes more sense - char* string or char *string?
When declaring a new instance of an object in Objective-C, does it make any difference where you put the asterisk?
Is this just a matter of personal preference?
NSString* string = #"";
vs.
NSString *string = #"";
It doesn't make a difference, but there are good reasons to put it in each place:
It makes sense to put it near the class, because that makes it feel like a type: NSString*, a pointer to a string. Sensible.
It makes sense to put it near the variable, because that's what's actually happening: * is dereference. When you dereference your pointer string, you get an NSString. *string is an NSString. Sensible.
You may want to go with the latter because that's the way the compiler is thinking, so: NSString* oneString, anotherString will not work, whereas NSString *oneString, *anotherString is correct.
It's simply a matter of preference. Putting the * next to the type emphasizes that it's part of the type, i.e. "pointer to an NSString". However, this is usually frowned upon, because it ignores the fact that the * associates with the nearest variable name, not the type name. For instance, the following doesn't work:
NSString* a = #"string1", b = #"string2
This is because a is a pointer, but b is not.
Putting the * next to the variable name is, in my opinion, more of a C/C++ convention, because it emphasizes that the * and the variable name together act kind of like a variable.
Personally, I put a space on both sides of the *.
Another question that asked the same thing is here:
Declaring pointers; asterisk on the left or right of the space between the type and name?
It doesnt make the difference wher you put that pointer symbol. If you declare multiple objects in single line, you do it like NSString *str1, *str2. So its more appropriate to put that asterisk close to object. I prefer it close to object instance.

Assigning object pointers

Is this pointer assignment correct?
customclass.somearray = &*otherarray;
where somearray and otherarray are NSArray objects.
If not, how do I solve my problem:
I want to share this otherarray object with customclass.somearray. And I want all changes
made to customclass.somearray to be made to the original otherarray too.
Doing it this way, it works. I just want to ask, is it correct?
Your two variables are pointers of the same type, so just assign one to the other:
customclass.somearray = otherarray;
The way you have written this is unnecessary. Using the dereference operator * essentially gives you the "contents" of the pointer. The address-of operator & correspondingly gives you the address of whatever you apply it to. Your pointer otherarray contains an address. If you dereference that address and then take the address of that, you end up right back where you started.
Be aware that the left side of this assignment is a property access (assuming that customclass is also an object and not just a struct). This means that the compiler will change your expression into:
[customclass setSomearray:&*otherarray];
// And my version will be changed into:
[customclass setSomearray:otherarray];
That is, it becomes a method call rather than a simple assignment. This does not affect the syntax you should use, however.
When working in Objective-C, you never deal with objects directly, but always refer to them via pointers. Always. In C++, you can declare an actual object on the stack, for example, but you never do that in Objective-C. So, if you have:
NSArray *otherArray = [NSArray arrayWithObjects:#"foo", #"bar", nil];
then otherArray is a pointer to an instance of NSArray. Likewise, your somearray property will be of type NSArray*, so the types will match and you can just assign one to the other:
customclass.somearray = otherarray;
Hope that helps.

What does assigning a literal string to an NSString with "=" actually do?

What does the following line actually do?
string = #"Some text";
Assuming that "string" is declared thusly in the header:
NSString *string;
What does the "=" actually do here? What does it do to "string"'s reference count? In particular, assuming that for some reason "string" is not otherwise assigned to, does it need to be released?
Thanks!
The assignment is just that. The string pointer is basically a label that points to specific address in memory. Reassignment statement would point that label to another address in memory!
It doesn't change reference counting or do anything beyond that in Objective-C. You need to maintain the reference count yourself, if you are running in a non-garbage-collection environment:
[string release];
string = [#"Some text" retain];
However, string literals don't need to be managed, as they get allocated statically and never get deallocated! So the release and retain methods are just NOOPs (i.e. no operations). You can safely omit them.
What does the following line actually do?
string = #"Some text";
Assuming that "string" is declared thusly in the header:
NSString *string;
What does the "=" actually do here? What does it do to "string"'s reference count?
string is not a string.
string is, in fact, not any other kind of Cocoa object, either.
string is a variable, which you've created to hold an instance of NSString. The assignment operator puts something into a variable*. In your example above, you create a literal string, and put that into the variable.
Since string is a variable, not a Cocoa object, it has no reference count.
Assigning an object somewhere can extend the object's lifetime in garbage-collected code (only on the Mac). See the Memory Management Programming Guide for Cocoa for more details.
*Or a C array. Don't confuse these with Cocoa arrays; they're not interchangeable, and you can't use the assignment operator to put things into a Cocoa collection (not in Objective-C, anyway).
When you use a literal like in this case, it is just syntactic sugar to quickly create an NSString object. Once created, the object behaves just like another other. The difference here is that your string is compiled into the program instead of created dynamically.