IOS objective-C instance vars -- what's the difference - objective-c

What is the difference between declaring variables in the interface section vs. in the implementation section outside of a method.

Do you mean in the ivar block in the implementation, as in
#implementation MyClass {
id someIvar;
}
// methods go here
#end
If so, then the only difference is visibility to other code. At runtime, the ivar will be indistinguishable from one declared in the #interface section. However, code outside the class can see ivars declared in #interfaces, and unless those ivars are marked with #protected or #private, then the other classes can reach in and twiddle the ivars. But ivars declared in the #implementation are not even visible to code outside, so they cannot touch the ivars.
For the most part, this is just a code cleanliness issue. Nothing should go in the header file unless it's meant to be public. So why put ivars there?
As Josh Caswell noted, ivars declared in this fashion require a recent version of Clang.
The alternative interpretation of your question is you have code like
#implementation MyClass
- (void)someMethod { /* ... */ }
NSString *var;
- (void)otherMethod { /* ... */ }
#end
If this is what you meant, then the answer is, don't do that. In this code snippet we've declared a global variable named var rather than an instance variable. The location of the variable inside the #implementation block is irrelevant, it's exactly identical to a global variable in C (because that's what it is).

A variable declared in the #interface is an instance variable. In more recent compilers instance variables can also be declared in a block in the #implementation in a similar way to doing so in the #interface - this effects their visibility but not their lifetime.
A variable declared "outside of a method" in the implementation, as in:
#implementation
static int CallCount = 0;
is the closest thing Objective-C has to a class variable - a variable which all instances of a class share, as opposed to instance variables where each object instance has its own variable.
Such a variable has execution lifetime - it exists throughout a single execution of the whole application - just as typical class variables do in other languages. (The lifetime of instance variables is that of the object instance they belong to.)
The use of static further limits the visibility (not its lifetime) of the variable name to just the file containing the declaration - like a private class variable in other languages. Note that, unlike most languages class variables, variables declared in an #implementation without a static qualifier are added to the global namespace and thus increase the opportunities for name collisions - this is why they are not real class variables.
Such class variables are often initialized using the class method + initialize, just as instance variables are initialized using the instance method - init.

Declaring them in a class extension is often used in attempt to hide the instance variables and associated accessors from the client. Neither approach truly hides them, but hiding them is usually an improvement, and is available only if all compilers you need support it.

Related

Questions about instance variable, properties, implementation and interfaces

I have been programming for the iOS platform for the last few years but mainly using swift. In the recent months though, I have been tasked with a project using Objective C, and while I like it and found it easy to learn, there are some questions mainly about variables that I still don't quite understand.
1) What is the difference between declaring an instance variable and a property? Since the compiler automatically creates an instance variable for every property, is there any real advantage besides being able to pass in some parameters like atomic, nonatomic, strong, weak, assign, etc?
2) What is the difference between declaring variables in the #implementation or properties #interface inside the .m file?
From what I understand, declaring in the #implementation makes it a static variable and declaring it in the #interface makes it an instance variable, is that correct? Also why do classes that inherit from UIViewController (for example) already have an #interface in the .m file and classes that inherit from NSObject don't?
3) (Personal Question) Do you usually set a property to be atomic or nonatomic? I find that atomic is better because while it may be slower it is thread safe, but I see most people using nonatomic. Is the speed difference still noticeable nowadays with the amount of power we have?
4) Whenever I declare two instance variables with the same name in the #implementation in two different classes I get a "duplicate symbol" error. Why does this happen?
Just another simple question out of curiosity:
I see many questions where in the code the #interface has curly braces, but in my code I've never seen it, rather it ends with a #end like the #implementation file. Was this in earlier versions of Obj-C or is there any real difference?
Thank you so much, I know these are 4 or 5 questions, but I jumped so quickly into a project and I think I really need to learn the basics, which I skipped because I could not find answers to this questions.
1) What is the difference between declaring an instance variable and a property? Since the compiler automatically creates an instance variable for every property, is there any real advantage besides being able to pass in some parameters like atomic, nonatomic, strong, weak, assign, etc?
A property may or may not be backed by an instance variable. By default they are but you can declare a property and the explicitly provide both a getter and setter (if not read-only). Then the property will not have an implicitly declared ivar. Properties make it easy to indicate whether it is atomic or not, whether it is read-only or not, and it lets you indicate the memory management (strong, weak, copy, assign). Properties also provide support for key-value observing.
If you want a simple variable used privately without the need for any of those features, then a direct ivar without a property is over so slightly more efficient.
See Is there a difference between an "instance variable" and a "property" in Objective-c? for more details.
2) What is the difference between declaring variables in the #implementation or properties #interface inside the .m file? From what I understand, declaring in the #implementation makes it a static variable and declaring it in the #interface makes it an instance variable, is that correct? Also why do classes that inherit from UIViewController (for example) already have an #interface in the .m file and classes that inherit from NSObject don't?
The private #interface Whatever () in the .m is known as the class extension. It's basically a special unnamed category. There is no difference between declaring ivars there or in the #implementation block.
Personally I use the class extension to privately conform to protocols and to declare private properties. I use the #implementation block to declare private ivars.
Variables in the #implementation block are normal instance variables if they are put in the curly braces.
#implementation {
// ivars here
}
// variables here are globals. Same as before #implementation or after #end
// methods
#end
Without the curly braces those variables become globals.
See Difference between variables in interface Object() {} and #implementation Object #end and Difference Between Declaring a Variable Under #Implementation And #Interface Under .m file for more details.
3) (Personal Question) Do you usually set a property to be atomic or nonatomic? I find that atomic is better because while it may be slower it is thread safe, but I see most people using nonatomic. Is the speed difference still noticeable nowadays with the amount of power we have?
Atomic properties are not really thread safe. It just means the assignment is atomic and a read is atomic but it doesn't really mean thread safe in the broader sense.
See What's the difference between the atomic and nonatomic attributes? for a much more thorough discussion.
4) Whenever I declare two instance variables with the same name in the #implementation in two different classes I get a "duplicate symbol" error. Why does this happen?
See #2. You must not have your variables in the #implementation block curly braces. Put the variables where they belong and the problem goes away.
If you actually want the variable to be a file static, put it before the #implementation to make it clear that it isn't part of the class and prefix the variable declaration with static. Then if you happen to have two with the same name in different files, there won't be a duplication problem if they are static.
1) What is the difference between declaring an instance variable and a property? Since the compiler automatically creates an instance variable for every property, is there any real advantage besides being able to pass in some parameters like atomic, nonatomic, strong, weak, assign, etc?
Properties are really just methods wrapped in a syntax. They're intended to be called by other classes, assuming they're publicly provided. Instance variable is more like a field access in C. You should probably default to using properties (they support KVO, are safe on nil, etc.). You should certainly default to using properties for getting/setting, except possibly in the initializer.
Note, though, that the compiler does not always create instance variables. If you provide both getter and setter, you'll need to tell it to with #synthesize foo=_foo;.
2) What is the difference between declaring variables in the #implementation or #interface inside the .m file? From what I understand, declaring in the #implementation makes it a static variable and declaring it in the #interface makes it an instance variable, is that correct? Also why do classes that inherit from UIViewController (for example) already have an #interface in the .m file and classes that inherit from NSObject don't?
Historically, instance variables could only be defined in the #interface.
3) (Personal Question) Do you usually set a property to be atomic or nonatomic? I find that atomic is better because while it may be slower it is thread safe, but I see most people using nonatomic. Is the speed difference still noticeable nowadays with the amount of power we have?
The reason for using nonatomic is that atomic doesn't really solve thread safety as much as you'd think. For example, this is still thread unsafe, even if the property is set to atomic (since the value of foo could change between the read and write):
self.foo = self.foo + 1;
For this reason I think most favor nonatomic and handling thread safety specifically when needed.

In modern Objective-C coding, should ivar be replaced by property declaration as best practice? [duplicate]

This question already has answers here:
Must every ivar be a property?
(4 answers)
Is the use of instance variables discouraged? [duplicate]
(1 answer)
Closed 9 years ago.
I am refactoring old code and wonder - with the advent of auto-synthesized properties and class extension, should most instance variables declarations be done in the form of properties as best practice?
Yes, best practice is to use properties, either in the interface file or implementation file class extension based on wether the property is by design public or private to the class.
It would depend on your coding style. Generally, put ivars that you want accessible to other classes as properties in the .h-file.
If you declare properties but leave #synthesize to the compiler, they will automatically be synthesized so that the property myInstanceVariable is internally called _myInstanceVariable.
Accessing _myInstanceVariable directly means that you will bypass any setters/getters which is sometimes desired internally in classes, especially when the getter creates an object.
However, often when I have internal simple ivars which don't require any setter/getter, I use the ivars directly in the class extension:
// MyClass.m
#import MyClass.h
#interface MyClass() {
BOOL _simpleInternalVariable;
NSUInteger _anotherSimpleInternalVariable;
}
#end
#implementation MyClass
- (void)someMethod
{
_simpleInternalVariable = YES;
_anotherSimpleInternalVariable = 4;
}
#end
This yields exactly the same result as #property BOOL simpleInternalVariable; except that you are sure that no setter/getter is automatically created by the compiler. I sometimes prefer this way because you can't write self.simpleInternalVariable. Writing self.ivar means a getter runs somewhere but you don't always know if it's a custom getter or synthesized getter. When writing _ivar, I always know that I'm dealing with the ivar directly.
For objects though, I always use properties both in the .h- and .m-files. I could theoretically do the same thing I did above with objects, but it's just a reflex from the non-ARC days where you always wanted the compiler to generate setters which retained/released objects.

Difference between a property and a global variable [objective c]

I'm wondering what the difference between a class's public global variable and a class's property is (Objective-C primarily iOS programming). Only thing I notice is that you have to use pointer notation -> to access a class's global variable rather than a dot.
I've read that changing code from using globals to using properties can be a program breaking change. Is that true and if so, why?
Thanks!
Edit:
Block.h
Public Global Variable (I think?) [Edit: I now understand this is an Instance Variable, thanks]
#interface Block : GameObject {
#public
int type;
SKEmitterNode *particles;}
Property
#property (nonatomic) CGFloat x;
No, this is not a "global variable".
It is called an instance variable.
A property often (but not necessarily) has an associated instance variable, but the modern compilers hide that from you.
The big difference between using an instance variable is, that a property is always accessed through its accessors (in your case setX:(CGFLoat)x?and -(CGFloat)x`.
If you wanted, you could overwrite these accessors and do special handling, say, whenever the variable is accessed.
It is always possible to bypass the accessors by using the instance variable directly. In a case of an auto-synthesized iVar, this would be _x.
Note that the -> is not necessary in either case
Even a class property is backed by a class variable even though it is not global.
But with a property one has additional gatekeepers guarding access to the variable:
You can make the property readonly.
Finetune memory semantics (copy, assign, etc).
By using KVO it is easy to let changes propagate automatically.

Is it OK to use the instance variables created for auto-synthesized properties?

Currently I can write a class like this:
#interface Foo
#property(assign) float bar;
#end
#implementation Foo
- (void) someMethod
{
_bar = 4;
}
#end
It’s convenient that I can leave out the #synthesize boilerplate list, and if I can get used to the underscore notation, I get the nice readable rule that everything named _foo is an instance variable. Is it OK to use the auto-generated instance variables like this? I mean, maybe they’re supposed to be invisible even to the class author?
Yes, it is absolutely OK to use these variables.
Dropping the #synthesize requirement altogether was a convenience: the #synthesize xyz is now inserted implicitly - that is the only difference. Designers of the compiler reasoned that since they can unambiguously identify situations when you want to synthesize accessors vs. situations when you provide custom implementations, it is reasonable to stop asking you for an explicit #synthesize.
Is it OK to use the instance variables created for auto-synthesized properties?
Absolutely
It’s convenient that I can leave out the #synthesize boilerplate list, and if I can get used to the underscore notation, I get the nice readable rule that everything named _foo is an instance variable.
Of course, you also have the ability to specify a name using #synthesize foo = f00;.
Is it OK to use the auto-generated instance variables like this? I mean, aren’t they supposed to be invisible even to the class author?
Nope. It is necessary for them to be internally accessible. That's less frequent if you are using ARC, but the common case where you would access them directly is initialization and destruction (cases where the accessor methods should not be used).

share a property among different instance of the same class

Is it possible to share one parameter of a class among all the instances of this class, in objective-c?:
#interface Class1 : NSObject {
NSString* shared; /** shared among instance (this is not, but defined somehow) **/
NSString* non_shared; /** other parameters non shared **/
}
In the program then, each instance of Class1 has its own non_shared variables (as usual), but all access the same shared one (when one instance changes it all can see it).
One possibility is to hide the variable as a property and use a singleton in the setter/getter functions, but I don't know if there is a simple way.
Thanks,
Edu
Class variables (called static in many other OOP languages) are actually a bit of a pain in Objective-C. You have to declare a static global variable in the class' module (.m) file and reference that variable. You should add class-level getter/setters to encapsulate access to the static global variable. Your getter can alloc/init an object and put it in the variable if it is uninitialized before returning it.
If the static variable holds an instance (e.g. an NSString instance in your example), you need to make sure it doesn't get alloc/initialized more than once. Take a look at dispatch_once if you're on OS X 10.6 or greater to guarantee single initialization.