I know that it is possible in Objective C to define an instance variable without a property when I use curly braces in the top of the interface or the implementation. But what is the advantage when I do that?
I think your question should be comparing to property what is the advantage of defining instance variables.
Most property is backed by a instance variables. By default, a readwrite property will be backed by an instance variable, which will be synthesized automatically by the compiler. (A readonly property won't synthesize an instance variable, it only synthesizes a getter method which a readwrite property synthesize an instance variable and a getter and a setter method)
So property provides methods that synthesized by compiler to access the instance variable. I can't say which one has any advantages, just use the one which is proper to your case.
You may need to learn more about property. Properties Encapsulate an Object’s Values
The most advantage is this variables actually can be private/protected/public members according to the keyword (#private/#protected/#public) you set.
Take a look at this question
Related
I was wondering why assigning values to properties in another class causes EXC_BAD_ACCESS. I can't seem to figure out why.
1.) The value being sent into the setter is non-nil;
2.) When trying to assign the value, EXC_BAD_ACCESS happens, the variable is nil;
Using this pattern in both Cocoa and Cocoa Touch applications both causes EXC_BAD_ACCESS, so I don't think it's the platform, but I believe it's the pattern I'm using.
My questions are, is it when the variables are assigned, or is it the way I'm creating the properties?
I have created a dummy project which is seen in the pictures below.
Any help is appreciated.
EDIT: Doing some digging, I changed the name of the setter's variable (not the property name) to firstName__. Basically, the code in the setter for setFirstName:
- (void)setFirstName:(NSString *)firstName__
{
self.firstName = firstName__;
}
Doing this cleared up a little confusion by saying firstName__ (and not self.firstName) is equal to nil, even though in the AppDelegate, the value is non-nil.
Your problem is recursion. In the setter, you are calling the setter method again, and again and again.
When you declare
self.firstName = first name__;
is basically the equivalent of
[self setFirstName:first name__];
So the method is calling itself which doesn't make much sense to do.
You first need to wrap your head around properties and instance variables.
Objective C class instances often contain instance variables that hold values.
Even though it is possible to expose these variables to outside world via #public qualifier, this is not the established convention.
The convention is to have properties, which behind the scenes are a "wrapper" around private instance variable.
Since in Objective C you can only communicate with other objects via messages, to be able to access the values of instance variable you have setter and getter methods that are invoked when you send an appropriate message to the object.
Modern objective C creates instance variable for you implicitly when you declare properties. It is often said that those properties are backed by instance variables.
Normally there is no reason to explicitly implement setters and getters, as the compiler does this for you behind the scenes. (in a same manner, it also creates those instance variables for you)
But if you want to implement setters explicitly, you need to set the instance variable in the setter, not call the setter itself again (via dot notation convention) as I explained above.
Implicitly created instance variables have a naming convention with underscore as prefix. In your case it is
_firstName
When you declare a property called firstName, you also get an instance variable
_firstName
You setter should look like this
-(void)setFirstName:(NSString *)firstName
{
_firstName = firstName;
}
And getter
-(NSstring *)getFirstName
{
return _firstName;
}
I keep seeing things like this in example Objective C code:
_myProp = newValue;
As far as I understand, creating a property myProp will create the actual variable as _myProp, and two accessor methods which are (by default) myProp (the getter) and setMyProp (the setter).
My question is, why do I keep seeing example code that by-passes the accessor methods and gets at the variable directly? Is there any advantage to this?
There are occasions where you don't want to declare a property and instead just use a private ivar.
If, on the other hand, there is a property declaration there should be no reason to directly access the ivar, except in the implementation of the accessors.
Sometimes people want to bypass the side effects of accessors and use the ivar directly. This is usually a sign of an architectural flaw, though.
There are two times that I use the ivar directly.
When overriding the getter or setter. If you use the property self.blah inside the getter or setter it creates an infinite loop.
In the init method of a class.
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.
When using Objective-C properties can you stop creating instance variables altogether or do explicit instance variables (not the ones synthesized by the properties) still serve a purpose where properties would be inappropriate?
can you stop creating instance variables altogether
No, you can't (in a sense). What you can do is stop declaring them if you have properties. If you synthesize a property and you haven't declared the instvar, it will get declared for you, so you are creating an instance variable, just not explicitly.
do they still serve a purpose where properties would be inappropriate?
It used to be the advice to create properties for everything because having synthesized properties does almost all of the retains and releases for you. However, with ARC that reason for using properties to wrap the memory management has gone away. The advice now (for ARC) is, I believe, use properties to declare your external interface, but use direct instance variables where the variable is part of the object's internal state.
That's a good reason to adopt ARC: properties revert to their true purpose only of being part of the class's API and it's no longer necessary to use them as a hacky way to hide memory management work.
Edit
One more thing: you can now declare instance variables in the #implementation so there is now no need to leak any implementation details in the #interface. i.e.
#implementation MyClass
{
NSString* myString;
}
// method definitions
#end
And I'm pretty sure it works in categories too. - see comment below
I recommend declaring everything as properties and avoiding manual ivars altogether. There is no real upside to manually creating ivars. Declare public properties in your header #interface, declare private properties in a private class extension in your .m file.
To some of JeremyP's points, internal use of accessors still has significant value under ARC, even though memory management is no longer a significant concern. It ensures that KVO works properly, subclasses better, supports custom setters (particularly for things like NSTimer), supports custom getters (such as for lazy instantiation), etc. It is exceedingly error-prone to have a mix of accessors and ivars. It's far too easy to forget which you need to access in which way. Consistency is the hallmark of good ObjC.
If you absolutely must declare an ivar for some reason, then you should do it in the #implementation block as JeremyP notes.
UPDATE (Oct-2013):
Apple's guidance (From Programming with Objective-C: Encapsulating Data):
Most Properties Are Backed by Instance Variables
In general, you should use accessor methods or dot syntax for property access even if you’re accessing an object’s properties from within its own implementation, in which case you should use self:
...
The exception to this rule is when writing initialization, deallocation or custom accessor methods, as described later in this section.
This question was addressed before here
When you use synthesize the instance variables are handled and instantiated for you. If you're using Lion with the new version of XCode also take a look at the various properties in ARC in Transitioning to ARC
you can always access properties from outside. So if you want a variable only to be read from inside a class you still have to declare a iVar. Also accessing a public ivar with object->ivar is slightly faster than using a method-call.
Since Objective-C doesn't support const instance variables in classes what are some alternatives to ensure the value of the variable doesn't get changed? I do not want to resort to preprocessor #defines because I would prefer class variables. Also, is there a reason const instance variables aren't supported?
Objects in Objective-C are constructed differently than those in C++ or Java. All instance variables are initialized to zero by the alloc method, before the init method is called, so it would be too late by the time init is called to change a const instance variable. Obviously the compiler writers could modify the compiler to support changing a const instance variable in an init method, but they haven't done so.
Typically you just make your instance variables #private and expose them using accessor methods. If you don't want an instance variable's value to change, don't expose a setter method and don't modify the variable in your class implementation.
If you drop support for 32-bit Mac OS X, you can put your instance variables in your #implementation instead of your #interface, which completely protects them from meddling by other classes.