This question already has answers here:
Class variable defined at #implementation rather than #interface?
(6 answers)
Closed 7 years ago.
What is the difference between
#implementation aClass {
aType *aVariable
}
- (void)aMethod: {
}
and
#implementation bClass
bType *bVariable
- (void)bMethod: {
}
Is bVariable global?
Is bVariable global?
Yes.
Objective-C is an extension of C and this is a standard C global variable declaration.
You probably should also look up the meanings of static and extern in relation to global variables in C.
HTH
Addendum
So back to the first question, the difference is that I can't define bVariable again in my entire project, while the term aVariable can be reused?
Short answer: No, at least not how you've expressed the question.
Long answer: What you have are two declarations each of which declare a variable and associate a name (or identifier) - aVariable, bVariable - with that variable. As well as a type, which is part of the declaration, a variable has a lifetime - how long the variable exists - and a scope - the part of the program in which the variable is accessible. Scopes can nest, and inner scopes can contain declarations which use the same name's as those in outer scopes, which results in hiding - the variable in the outer scope cannot be directly accessed via its name.
A global variable is one whose lifetime is the whole execution of the program, however the scope in which a global variable is (directly) accessible need not be the whole program (c.f. the static qualifier in (Objective-)C), and different global variables with non-overlapping scopes can have the same name.
An instance variable is one whose lifetime is the same as that of its owning class instance, and whose scope is the members of the class.
There are also local variables, whose lifetime and scope is the containing method, function, block etc. that declare them.
The above is just a quick summary, you should look up the meanings of the all italicised terms.
Related
What is the difference between the code below?
#implementation MyClass
static int myVar =0;
int _myVar =0;
I am getting same values for different objects of MyClass and both are visible to the all methods of MyClass...
Static and global variable differ a lot in their behaviour to life and scope. First, let me distinguish between life and scope. Life of an object determines whether the object is still in the memory (of the process) whereas scope of the object is whether can I know the variable by its name at this position. It is possible that object is live, but not visible (not in scope) but not that object is not alive but in scope (except for dynamically allocated objects where you refer object through pointers).
Static variables are local in scope to their module in which they are defined, but life is throughout the program. Say for a static variable inside a function cannot be called from outside the function (because it's not in scope) but is alive and exists in memory. The next time this function is entered (within the same program) the same chunk of memory would be accessed now retaining the variables old value and no new memory is allocated this time for this variable like other variables in the function (automatic variables). So basically the variable persists throughout the program. Similarly if a static variable is defined in a global space (say at beginning of file) then this variable will be
accessible only in this file (file scope).
On the other hand global variables have to be defined globally, persists (life is) throughout the program, scope is also throughout the program. This means such variables can be accessed from any function, any file of the program.
So if you have a global variable and u r distributing ur files as a library and you want others to not access your global variable, you may make it static by just prefixing keyword static (of course if same variable is not required in other files of yours).
Neither of those variables are related to MyClass and both are global, which is why you are seeing the same value in all instances of MyClass. If you wanted to make _myVar an instance variable then it needs to go between brackets:
#implementation MyClass {
int _myVar;
}
...
#end
The difference between the variables in your code is that the static variable cannot be accessed outside the scope of the implementation file (which I assume is called MyClass.m), while the non-static one can be accessed from anywhere in the application, however you'd need to keep the compiler happy with an extern int _myVar; in any code that wants to access it; this is normally done by putting that extern declaration in a header file.
static limits the scope of your variable. In your case variable will be visible within MyClass file.
However, declaration of variable without static means that variable is automatic by default. It means that your static will live throughout all method calls and automatic will be allocated when you call a method and then at some point deallocated.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Arrow operator (->) usage in C
Dot (“.”) operator and arrow (“->”) operator use in C vs. Objective-C
I'm a newbie looking at a freeware/open-source program last updated in 2008, and I don't recognize the -> in the following notation:
- (id)copyWithZone:(NSZone *)zone
{
GFIPGeniusItem * newItem = [[[self class] allocWithZone:zone] init];
newItem->_stringValue = [_stringValue copy];
newItem->_imageURL = [_imageURL copy];
newItem->_webResourceURL = [_webResourceURL copy];
newItem->_speakableStringValue = [_speakableStringValue copy];
newItem->_soundURL = [_soundURL copy];
return newItem;
}
I'm assuming it's allowing some sort of shortcut, but I'd love to specifically what it does.
It's a way to directly access an instance variable within an ObjC object from outside that object. (The syntax and -> is borrowed from C structs, behaving as if the reference were a pointer-to-structure).
This access mechanism is almost vestigial at this point, and very uncommonly seen in modern ObjC code, because good encapsulation requires the use of accessors and properties, not touching instance variables directly. It's legitimate in some very special cases, though, and this is one of them:
When copying an object, you want to get a resulting copy that matches exactly the state of the current self. The cleanest way of achieving this is often to set the copy's ivars explicitly, to prevent any side-effects that the init overloads or accessors might cause. It's "safe" because the code doing it is still located within the class that's in question, so if you needed to change or add ivars, you could update this code as well with the knowledge of anything else that might require.
Doing this from outside the class in question is bad form, and there's no good reason to do it.
In Objective-C you have some kind of two variable type accessors. The one everybody should know is the "." one (e.g. Class.variable). This type calls either the appropriate getter or setter.
Now, the other type - the one you asked for - is for in-class usage. Obviously, as the getter or setter gets called automatically with the "." notation you need a way to set the variable without a setter (calling the setter in the setter itself results in an endless loop). Therefore, this "->" notation is used -> simply, it is the direct-access mode.
Usually, Objective-C the variable name for both notations is the same but some prefer to have the in-class notation variable name beginning with "_". This is achieved by editing the #synthesize variable line to #synthesize variable = _variable.
That's a pointer indirection operator. a->b means the same thing as (*a).b (where the . is the structure member access operator, not Objective-C's property dot syntax).
When you say:
newItem->_stringValue
you're directly accessing the _stringValue instance variable of the object to which newItem points.
The -> operator is very common in C++, but not so much in Objective-C.
In Objective C, like in C++, the p->m notation is equivalent to (*p).m This is, the dereference of the pointer to the base type followed by a call to the corresponding method or property.
So in your case, using the other notation it would look like this:
(*newItem)._stringValue = [_stringValue copy];
(It's more common to use the -> operator)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Prefixing property names with an underscore in Objective C
When synthesizing properties I found out that someone is doing:
#synthesize myVar = _myVar;
what is "_myVar" and which is the difference with simply doing :
#synthesize myVar;
Lastly when I should prefer the first solution to the last one?
Thanks
Luca
What _myVar really is in your example, is the name of the ivar that is backing your property. By default, when you synthesize a property, an ivar of the same name is created for you. So, you can use your property to set your ivar through setter/getter or the _myVar to directly access your variable (bypassing KVC/KVO of course).
EDIT:
From Apple's Coding Guidelines for Cocoa
...In many cases, when you use a declared property you also synthesize
a corresponding instance variable.
Make sure the name of the instance variable concisely describes the
attribute stored. Usually, you should not access instance variables
directly, instead you should use accessor methods (you do access
instance variables directly in init and dealloc methods). To help to
signal this, prefix instance variable names with an underscore (_)...
If you want to use some existing data member in setter and getter then it can be specify like that.
e.g. #synthesize personName=pName;
by this we can use pName instead of personName as per our convenience.
It the name of the private variable.
Se my answer on an other post: answer
Are "local object variables" the variables that are used or initialized in a method, or are they the arguments taken in? I can't find this term in Xcode's documentation or Google.
I found this in the Objective-C book that I'm using. The full quote is
Local variables that are basic C data types have no default initial value, so you must set them to some value before using them. The three local variables in the reduce method are set to values before they are used, so that's not a problem here. Local object variables are initialized to nil by default. Unlike your instance variables (which retain their values through method calls), these local variables have no memory. Therefore, after the method returns, the values of these variables disappear. Every time a method is called, each local variable defined in that method is reinitialized to the value specified (if any) with the variable's declaration."
Based on your comment, I understand what the book means. Local variables are variables local to a particular scope (denoted by braces '{}' in C and Objective-C). Local variables are declared in the scope where they're used, as opposed to global variables which can be seen and used globally (to a file, multiple files or the whole program depending on declaration visibility). Instance variables are part of a class instance and can be used by any of its methods (and other classes too if declared using #public, though that's generally not good practice).
Primitive local variables are local variables whose type is a C primitive like int, float, char, etc. What the book is calling "local object variables" are simply local variables whose type is (a pointer to) an Objective-C object. Examples are NSString *, NSDictionary * and id.
Local variables are stored on the stack, as opposed to the heap. Variables on the stack go away at the end of the method or function call where they were declared. This Stack Overflow question has some good answers explaining the difference between the stack and the heap: What and where are the stack and heap?
The first result of a Google search for "local variables objective-c": http://blog.ablepear.com/2010/04/objective-c-tuesdays-local-variables.html .
Local variables are defined in the method and scope of the variables that have existed inside the method itself.
int helloness;
#interface test : NSObject
#end
vs
#interface test : NSObject{
int helloness;
}
#end
Do I understand that following are true and the only meaningful differences between the above two blocks:
in both blocks, the implementation of test.m can use helloness variable internally, like an ivar
in the first block, helloness will exist for any class that imports this .h but is otherwise private only to test.m in the second block
In the first block, is this technically what is considered a "global variable" in that any class that imports this will have access to the same contents of helloness?
What happens if multiple header files have a declaration for helloness and you import them all?
Similar to this, consider this implementation:
#implementation AClass
int food=5;
Here, food acts like an internal iVar, even though it was not declared in any #interface ?
In your first example, helloness is a global variable. It can be seen by any file which imports that header. If you include multiple headers which also declare an int helloness variable, I believe you'll get a warning from the compiler, and all of them will point at the same memory location. If you include another header which declares a helloness of type other than int, I believe you'll get a compiler error.
In the second example, helloness is an instance variable (ivar). Its value (memory location) is specific to each instance of AClass. (Anything can access it: e.g. AClass *instance = [[AClass alloc] init]; instance->helloness = 7; However, direct access to ivars is generally avoided in ObjC -- we use accessors and/or properties instead.)
In the third case, food is still a global variable, but its visibility is restricted to the implementation file it's declared in. Any instance of AClass, as well as any other classes or categories or functions implemented in the same file, can reference food, and all those references are to the same memory location.
In your first example, helloness is a global variable. In your second example, it's an instance variable.
There can be only one global variable with a given name in your program. There is a copy of an instance variable for each instance of your class that's created during your program's execution. They're not semantically similar at all.
Having a global variable in a header file, as I presume you are doing in the first example since you refer to #importing it, is probably a bad idea. If it's not a tentative definition like yours is (for example if you instead had int helloness = 12;), you'll end up with multiply defined symbol errors at link time.
In your last example, food is still a global variable, but since it's likely to be in an implementation file (rather than a header), you probably won't run into any multiply defined symbol errors. It won't work like an instance variable, though - it's still a global variable.