First off, please forgive the stupidness of this question but Im not from a C/C++ background. I'm a little unclear about what the difference in roles between the .h and .m files when it comes to properties.
I understand the concept of interfaces, and I see that in part the .h file is an interface for the implementation, but what I am not clear on is this:
Why are properties/methods defined outside of the {} braces?
What am i defining in the braces when I write something like this:
IBOutlet UITextField *numberField;
Is this a field definition in an interface?
When I am adding the #Property lines to the .h files are these actual implementations of a n auto property or just an interface blueprint? If so is the #syntesis the actual implementation?
I guess my biggest confusion seems to be that if I want a property I'm defining what I need in three different places (1) in the interfaces braces, (2) as #property outside the braces and (3) with #synthesis in the .m file. This seems long winded, but its fine if I can work out what these three parts do.
Cheers, Chris.
I'll answer your questions below, but perhaps the best way to learn this stuff is to read some user-friendly notes intended for folks new to the language, such as the Learn Objective-C tutorial over at cocoadevcentral.
An example
I'd like to help answer your questions with an example (I love learning by example). Let's say you're a teacher writing a program that asks students a particular yes/no question, and keeps track of how many get it correct and how many students it has asked.
Here is a possible interface for this class:
#interface Question : NSObject {
NSString* questionStr;
int numTimesAsked;
int numCorrectAnswers;
}
#property (nonatomic, retain) NSString* questionStr;
#property (nonatomic, readonly) int numTimesAsked;
#property (nonatomic) int numCorrectAnswers;
#property (nonatomic) int numWrongAnswers;
- addAnswerWithTruthValue: (BOOL) isCorrect;
#end
The three variables inside the braces are instance variables, and every instance of your class will have its own values for each of those variables. Everything outside the braces but before #end is a declaration of a method (including the #property declarations).
(Side note: for many objects, it's useful to have retain properties, since you want to avoid the overhead of copying the object, and make sure it isn't released while you're using it. It's legal to retain an NSString as in this example, but it is often considered good practice to use copy instead of retain since an NSString* might actually point to an NSMutableString object, which may later change when your code expects it to stay the same.)
What #property does
When you declare a #property, you're doing two things:
Declaring a setter and getter method in the class's interface, and
Indicating how the setter and getter behave.
For the first one, it's enough to know that this line:
#property (nonatomic, retain) NSString* questionStr;
is basically the same as this:
- (NSString*) questionStr; // getter
- (void) setQuestionStr: (NSString) newQuestionStr; // setter
in the header. You literally are declaring those two methods; you can call them directly, or use the dot notation as a shortcut to call them for you.
The "basically" part in "basically the same" is the extra info given by keywords like nonatomic and retain.
The nonatomic keyword indicates that they're not necessarily thread-safe. The common retain keyword indicates that the object retains any value that's set, and releases previous values as they're let go.
For example:
// The correct answer to both questions is objectively YES.
Question* myQuestion = [[Question alloc] init];
NSString* question1 = [[NSString alloc] initWithString:#"Is pizza tasty?"];
// question1 has retain count of 1, from the call to alloc
myQuestion.questionStr = question1;
// question1 now has a retain count of 2
NSString* question2 = [[NSString alloc] initWithString:#"Free iPhone?"];
myQuestion.questionStr = question2;
// question1 has a retain count of 1, and question2 has retain count of 2
If the #property declaration for questionStr had been assign instead, then all the myQuestion.questionStr = statements would not have made any changes at all to the retain counts.
You can read a little more about properties here.
What IBOutlet and IBAction do
These are basically no-op words which act only as a way to tell Interface Builder which pieces of the header file to pay attention to. IBOutlet literally becomes an empty string when the compiler looks at it, and IBAction becomes the void return value. We do need them to work with Interface Builder, though, so they are important -- just not to the compiler.
Quick note on C structs and arrow vs dot notation
By the way, the data part of an Objective-C object is very similar to a C struct. If you have a pointer to a C struct, you can use arrow notation -> to refer to a specific part of the struct, like this:
struct MyStructType {
int i;
BOOL b;
};
struct MyStructType* myStruct;
myStruct->i = 3;
myStruct->b = TRUE; // or YES in Objective-C.
This same syntax works the same way in Objective-C:
Question* question = [[Question alloc] init];
question->questionStr = #"Is this a long answer?"; // YES
But when you do this, there is no method call happening behind the scenes, unlike the dot notation. With the dot notation, you're calling the setter (or getter if there's no = afterwards), and these two lines are the same:
question.questionStr = #"Chocolate?";
[question setQuestionStr:#"Chocolate?"];
It's often a good idea to avoid the arrow notation in favor of the dot notation, since the dot notation lets you enforce valid state -- for example, that the pointers your class has are always retained. You can even disallow others from using the arrow notation by declaring your instance variables as #private; they can still use the getter and setter to access it, if you declare a #property for it.
What #synthesize does
Now, when you get around to actually implementing your class, #synthesize says something like "make sure the getter and setter get implemented for this property." It does not say "implement both of these for me," because the compiler is polite enough to check for your own implementation first, and only fill in the pieces you've missed. You don't have to use #synthesize at all, even if you use #property out the wazoo -- you could always just provide your implementations for your setters and getters, if you're into that sort of thing.
You probably noticed in the Question interface above that there's a property which is not an instance variable (numWrongAnswers), which is fine because you're just declaring methods. In the example code here, you can see how this actually works:
#implementation Question
#synthesize questionStr, numTimesAsked, numCorrectAnswers;
- (void) setNumCorrectAnswers: (int) newCorrectAnswers {
// We assume the # increases, and represents new answers.
int numNew = newCorrectAnswers - numCorrectAnswers;
numTimesAsked += numNew;
numCorrectAnswers = newCorrectAnswers;
}
- (int) numWrongAnswers {
return numTimesAsked - numCorrectAnswers;
}
- (void) setNumWrongAnswers: (int) newWrongAnswers {
int numNew = newWrongAnswers - self.numWrongAnswers;
numTimesAsked += numNew;
}
- (void) addAnswerWithTruthValue: (BOOL) isCorrect {
if (isCorrect) {
self.numCorrectAnswers++;
} else {
self.numWrongAnswers++;
}
}
#end
One thing that's happening here is we're faking an instance variable called numWrongAnswers, which would be redundant information if we stored it in the class. Since we know numWrongAnswers + numCorrectAnswers = numTimesAsked at all times, we only need to store any two of these three data points, and we can always think in terms of the other one by using the two values we do know. The point here is to understand that a #property declaration is really just about declaring a setter and getter method, which usually corresponds to an actual instance variable -- but not always. The #synthesize keyword by default does correspond to an actual instance variable, so that it's easy for the compiler to fill in the implementation for you.
Reasons to have separate .h and .m files
By the way, the whole point of declaring methods in one file (the .h header file) and defining their implementation in another (the .m or methods file) is to help decouple the code. For example, if you only update one .m file in your project, you don't have to recompile the other .m files, since their object code will remain the same -- this saves time. Another advantage is that you can use a library that includes only header files and pre-compiled object code, or even dynamic libraries where you need the header file so the compiler is aware of which methods exist, but those methods aren't even linked in with your executable file. These advantages are hard to appreciate when you first start coding, but just the logical breakdown and encapsulation of implementation becomes useful after a short while.
I hope that's helpful!
methods are defined outside of the braces since the braces are meant to encapsulate the state of the object which can be argued does not include the instance or class methods.
What you are defining in the braces are instance variables that can be referenced as self.ivar
The #property and #synthesize directives simply setup accessors for you instance variables so you can set them by doing self.ivar = someVar. So in other words it sets up the "dot syntax" for you to use.
and to answer your finale question: To define a property or instance variable simply declare it in your .h file as a variable inside the braces. To setup accessor methods on that same property you need to do BOTH #property and #synthesize.
Well that is just Objective C syntax, methods and #property outside {} and variables inside {}.
#property is the way of telling that you are going to write getter and setters (kind of enforcing it), but you can write getter/setter without setting them #property. #property is in .h file because its declaration. And why it is outside {}, well as i said before its just the syntax, what we can do?
#synthesis will in actual implement getter and setters, if you dont synthesis but you have set them #property, you have to implement those getter and setters by your hand. And #synthesis is in .m file because its implementation.
Something more for you to read on this subject can be find here.
http://theocacao.com/document.page/510
The variables inside the brackets define the physical structure of your class. Those are the actual instance variables that store information.
The stuff outside the brackets make up the class's interface — methods and properties. A property in and of itself does not reserve any storage space or affect any variable — it just declares a generic interface for accessing something. Remember that a property doesn't have to have an underlying instance variable — for example, the totalPrice property in a ShoppingCart class might dynamically sum the prices of all the items in the cart.
Inside the implementation file, you tell the class how to actually do its work. For methods, obviously, you just supply an implementation. For a property, you can either provide accessor implementations yourself or ask it to synthesize accessors for an instance variable.
Related
All my research shows that there's no real usage for the #private directive - so I must be missing something and need you experts to chime in :-)
Assume we have 2 classes: a Car class and a SportsCar class, where SportsCar is a subclass of Car.
Here's the Car class:
#interface Car : NSObject {
NSString *make;
NSString *model;
#private
int numberOfBackSeatPassengers; // I'm making this a private iVar cause I'm just gonna
// say that all Sportscars will be 2-seaters and therefore shouldn't
// be able to set/get the number of back-seat passengers
}
#property (nonatomic, strong) NSString *make, *model;
// Now here's my first issue: if I also make "numberOfBackSeatPassengers" an #property
// then it seems like all subclasses of this Car class *WILL* be able to access it as
// well - even though I declared it as #private - but I'll do this anyway to make my point:
#property int numberOfBackSeatPassengers;
#end
The Implementation looks like this:
#implementation Car
#synthesize make, model, numberOfBackSeatPassengers;
#end
Now here's the Sportscar class:
#import "Car.h"
#interface Sportscar : Car
#property int turboEngineSize;
#end
And its implementation:
#import "Sportscar.h"
#implementation Sportscar
#synthesize turboEngineSize;
#end
In "main" I have this:
Car *car1 = [[Car alloc] init];
[car1 setMake:#"Chevy"];
[car1 setModel:#"Impala"];
[car1 setNumberOfBackSeatPassengers:3];
Sportscar *sports1 = [[Sportscar alloc] init];
[sports1 setMake:#"Audi"];
[sports1 setModel:#"tt"];
[sports1 setNumberOfBackSeatPassengers:3];
Obviously I'm able to set the NumberOfBackSeatPassengers on the Sportscar - even though that iVar was declared as #private - but that's because I made it an #property in "Car.h" which means that the synthesized getter and setter for it are Instance Methods, thereby available to all subclasses of Car.
The other option would have been to NOT declare numberOfBackSeatPassengers as an #property in "Car.h", keep it there as only a simple iVar, and instead manually create a Setter and Getter for it in the #implementation of "Car.m" like this:
-(void) setNumberOfBackSeatPassengers:(int)numPassgeners {
numberOfBackSeatPassengers = numPassgeners;
}
-(int)numberOfBackSeatPassengers {
return numberOfBackSeatPassengers;
}
This would have made the getter and setter for numberOfBackSeatPassengers available only within "Car.m" - which I suppose would make them "private" - but they'd be too private: I could never call them from Main, or from anywhere outside of "Car.m" Moreover, and this is the real point: doing it this way means the #private directive back in "Car.h" doesn't really come into play at all in any of this. I mean I could now go back to "Car.h", take out the "#private" directive there -- and my manual setter and getter for numberOfBackSeatPassengers would still work exactly the same as they are now, being supposedly private - so what's to be gained with "#private"? How does it truly come into play?
Can anyone shed any real light on this?
(And yes, I know I can extend my Car class in the #interface section of the "Car.m" file - through a category, or make numberOfBackSeatPassengers a readonly property first, then change it to readwrite, etc. - but these all seem like workarounds or "hacks" to making "#private" work. I just don't get how #private truly works on its own.)
=====================================================
EDIT - in response to aroth's comments below:
1) aroth's absolutely correct in saying that a subclass could still theoretically call a method that was NOT declared in its parent class's Header -- by using performSelector. I say "theoretically", cause in my case its not quite working correctly: if - in "main" - I call
[sportscar1 performSelector:#selector(setNumberOfBackSeatPassengers:)];
then I get some junk number inserted for numberOfBackSeatPassengers cause I can't explicitly pass-in a number as an argument when calling the method this way.
(Question: is there a way around this?)
2) aroth's also absolutely right in saying that in Sportscar we can simply override the Car class's setter and getter for numberOfBackSeatPassengers, and have these overriding methods reset it to 0, or give an error, etc. But while this is a very practical solution and seems to solve this particular problem, I feel like it doesn't address the larger issue of #private not really seeming to do what it ought to do.
3) Redesigning the logic to have a class for FourDoorCar and another one for TwoDoorCar and then continue building off of that is an interesting option - but that almost feels like now Objective-C's syntax is "forcing" itself on my programming logic and how I'm structuring my very project - and this feels like quite an imposition. Maybe I'm wrong and making too much out of this - but either way this all came about just because the #private isn't doing what it seems to promise...? Doesn't feel right.
At the end of the day I keep coming back to the same question: what good does #private actually do us? What benefits does it have, what does it "buy" me? It seems that if I want to have an iVar be private, I can just declare it in the ".m" file and not ever bother declaring it in the Header file in the first place. I mean am I right about this or not? or is there still some instance where you'd want to declare an iVar in the Header as #private, but not declare a setter and getter for it there in the Header - so those won't be explicitly available to subclasses - and have it all make sense?
Can we think of an actual example for this? Is there some sort of Car property that I'd want to declare as #private in the Header (as opposed to in the ".m") that would somehow benefit me?
I thought numberOfBackSeatPassengers would be a good example, but I'm not seeing how it'd really work in action, in actual code...
=========================================================================
EDIT #2 - Continuing the dialogue with #aroth :-)
#aroth - I absolutely agree that its much better/more organized to declare all iVars in the Header and not split things up so that some are in the Header and some are in the Implementation. That creates a mess and I really dislike that approach. (I noted in my original question that I don't want to use the Implementation and/or Category approach to address my question.)
-Also, yes, properties absolutely don't always have to be backed up by iVars.
-Regarding designing the Class appropriately, I concur that that of course is the key to good programming. The Car/Sportscar example is something I made up on the spot to give my question some context and I didn't invest any time considering its design merits/flaws. I think if we were to take your approach however - which seems quite logical for sure - and go with a Car class, a FourDoorCar subclass, a TwoDoorCar subclass, etc. - we could solve a lot of problems - but its still very likely that sooner or later we'll run into a situation where we'd perhaps want an #private iVar for one of our classes, and not want to create another subclass to deal with it.
I mean lets just assume that this would happen, for the sake of this discussion.
And so, if possible, I'd really like to think of a specific iVar for our Car class that it would make sense to have as #private, show in code how to use it, and discuss its scope and limitations.
I keep trying to think of a real-world example of some property of a Car that we would want only the Car to have - and that none of its subclasses should inherit.
I really thought numBackSeatPassengers would do the trick - and for the purposes of our discussion it still can, but, I'll just make up another one and call it phantomIVar :-)
And so:
#interface Car : NSObject {
#private
//int numberOfBackSeatPassengers;
int phantomIVar;
}
#property (nonatomic, strong) NSString *make, *model;
#end
The Implementation would be:
#implementation Car
#synthesize make, model;
-(void) setPhantomIVar:(int)i {
phantomIVar = i;
}
-(int)phantomIVar {
return phantomIVar;
}
#end
Which pretty much puts us back where we started :-)
At least that's how I feel.
I mean the only thing that the #private declaration seems to buy us is readability. So that now, anyone looking at the Header will be able to see that phantomIVar is an iVar of Car, and understand that its private. That's it.
In terms of functionality however, it didn't seem to do much. Cause its not like putting #private in front of phantomIVar freed us up to still be able write a setter/getter for it in the Header and have those be only accessible to Car class objects and not subclasses of Car. No, #private doesn't get you that. To get privacy you'd have to go in the Implementation file and write your setter and getter there. And ultimately in Objective-C there's no such thing as private methods. In Obj. C. they're all public.
aroth, please let me know if I got this right - and if not, where exactly I went wrong.
Many thanks :-)
This would have made the getter and setter for
numberOfBackSeatPassengers available only within "Car.m"
Not true. Those methods would still exist on every instance of Car and every instance of every object that extends Car, whether or not you declare them in your header file. The compiler wouldn't treat them as publicly visible and would complain if you tried to call them directly, but you'd still be able to call your getter and setter on any subclass of Car simply by using performSelector:.
In any case, if you have a #property there's no point is using #private on the ivar that backs it (and there's also no point in having an explicit ivar backing it, one will be created automatically for you when you use #synthesize; but that's a separate topic). I'd suggest that if SportsCar is meant to extend Car and never allow any backseat passengers to be recorded that the 'standard' way to do that would be to simply override the getter/setter methods in SportsCar to either always set/return 0 or to raise some error if an attempt is made to set a nonzero value.
Another option, since this property does not apply to all Car instances is to take it out of the base class entirely. You could, for example, have Car, and then derived from that have TwoDoorCar and FourDoorCar, and then have SportsCar be derived from TwoDoorCar. In this case you could declare numberOfBackSeatPassengers as a public property of FourDoorCar, as every four-door car should be able to accommodate passengers in the back seat.
To get back to the original question being asked, using #private on an ivar affects only the visibility of that ivar. It does not affect methods which make use of the ivar. So a subclass of Car will not be able to see the numberOfBackSeatPassengers ivar itself. But since you've created a public getter/setter for it, the subclass will of course be able to see those, and use them to modify the value of the ivar.
Edit
To briefly answer the updated question(s):
Yes, you can use NSInvocation to dynamically invoke a method that requires primitive parameters. Or you can use the approach discussed here, which is even more straightforward: Objective-C and use of SEL/IMP. Or you can use a NSNumber instead of an int and then use performSelector:withObject:.
I'm not sure what you're saying #private should be doing in this case. What is it that you think using #private should do?
I think this has less to do with syntax and more to do with principles of object-oriented design. If some cars do not have a back seat, then it is not really good object-oriented design to give the Car superclass a numberOfBackseatPassengers property. Doing that gives the object a field that does not actually apply to every instance of the object type. And when you start doing that you run into exactly the sort of problems you describe in your example. The purpose of a superclass is to contain functionality that is common to all of its derived types. If it has functionality that is common only to some of its derived types, then that is usually a design problem. In any case, it has nothing to do with Objective-C syntax or semantics.
As for what #private gets you, how about simplified organization of your class, for one thing? Yes you can declare an ivar in your implementation file to accomplish a similar effect, but is that really as convenient as having all the ivars declared in the header? On a reasonably complex project, will other developers be able to follow your code as easily if only some ivars are declared in the header and the rest are in the implementation file?
Without #private/#protected every ivar declared in a header would be public, which is definitely not good in an object-oriented environment for all the reasons Jonathan pointed out. So these access modifiers probably exist, first and foremost, to solve this issue.
As for use-cases, properties with getters/setters are probably not the best example. The purpose of getters/setters is virtually always to provide a public interface for modifying/querying the property value, and as noted in Objective-C it's not necessary to explicitly declare an ivar, in any scope, to back a synthesized property.
A better example may be IBOutlet's. You want these declared in your header so that XCode/Interface Builder can find them, but you don't want them exposed outside of your class implementation or (typically) even to subclasses of your class. So you would declare them in your header, and you generally would not add any getter/setter methods for these ivars.
Edit 2
For a specific example of where #private makes sense, what about something like:
#interface Car : NSObject {
#private
DataRecorder* blackBoxRecorder;
}
#property (nonatomic, strong) NSString *make, *model;
#end
We know that proposed regulations may require all cars on the road to include a built-in black-box/data recorder. So every Car must have one, and no subclass of Car should be able to tamper with blackBoxRecorder.
In this case having a setter method defined would not make sense. You might provide a public getter, or instead you might provide a public wrapper API around the DataRecorder that subclasses could use to log data. Something like -(void) logEventWithName:(NSString*)name andValue:(NSNumber*)value;. So subclasses can use the DataRecorder through the API, but they can't mess with the backing ivar itself to disable or modify the behavior of the mandated black-box/data recorder.
But in any case, yes, I'm in general agreement with your analysis. Having #private mostly impacts readability/maintainability of code. It needs to exist for Objective-C to be successful as an object-oriented programming language (if all ivars were public by default and there was no way to modify that, the language would be a complete mess), but what it does from a purely functional standpoint is not much. It's more of a logical/organizational tool. It assists with data hiding and allows you to keep all of your ivars in your header file(s), and that's about it.
You can declare the property as readonly in the Car class itself, or re-declare it as readonly only in the SportsCar class.
Also, #private doesn't have anything to do with properties - it only modifies the scope of the ivar itself.
I'm not familiar with the program language which has both property and instance variable.
So I don't know good ways to use property and instance variable.
Now I use only properties in my Objective-C code and I don't use any instance variables.
Do I need to use instance variable?
Or using only property is the best practice for Objective-C?
#interface ViewController : UIViewController
{
// instance variable
#public
int a;
}
// property
#property(nonatomic, strong) NSString *b;
#end
The basic difference between variable and property is that, you can give attributes to property. You can not give any attributes to variable.
So, if you wish to have any specific behavior like retaining the variable, accessing it atomically, have access out side the class, you should go for the properties.
If you simply want to access the variable with in the class and no special behavior is attached to that variable, no need to access it via property. You can directly use variable itself. It will improve the performance also.
There are some advantages a #property has over an ivar:
Memory management : Behind the scenes it will create a setter which creates the variable with correct memory management. It will save you some headaches because you can easily see how the memory management is done (strong/weak and retain/copy/assign).
Accessibility from other classes: if you declare your #property in the .h and #synthesize it in the .m you ivar will be public readable and writeable. You can prevent this with a privat class extension. You even can declare a #property public readonly and declare them internally readwrite via a privat class extension.
Eg: a private property
// [In the implementation file]
#interface MyClass ()
#property (nonatomic, retain) NSMutableArray* someData; // private!!
#end
#implementation MyClass #synthesize someData
#end
Custom getter and setter: If you like you can still write custom getter and setters and you can even just write a getter or setter and let the other one automatically #synthesize. And you can write custom logic into such a getter and setter e.g. you can reload a tableview after a #property has changed.
Automatic Key-Value-Observing (KVO) compliant: If you use or planning to use KVO you get it basically for free by just declaring the property. Nothing else need to be done!
Dot notation: You can access getter and setter via dot notation if you have the #property.
self.myIvar = (id) someThing;
[array addObject:self.myIvar];
If you need you iVar to be public it is simpler to write one #property than writing a getter and setter for a iVar
With a #property you do not need to declare in iVar (in iOS and 64bit Mac Os X applications). You can do it via the #synthesize:
#synthesize myiVar = _myIvar;
Use properties everywhere. Don't even declare instance variables, but synthesize them like this: #synthesize myProperty = _myProperty in order to differentiate them from property names. Properties are good way to cope with memory management as well. The only place you must use the synthesized instance variable is in the dealloc method.
The advantages of the properties are a lot:
- The accessor methods define how will you get and set the value of your instance variable.
- You can customize the accessor methods (for example to lazy instantiate an ivar or do something when a setting a new value like setNeedsDisplay.
- You don't cope with memory management when setting a new value - the setter takes care for releasing/retaining (depending how have you declared the property - retain/copy/assign/strong.
- Some multithreading stuff with the atomic/nonatomic attributes
- You can take advantage of the KVO, when using properties
- And least, but not last - don't worry about performance issues if you have concernes that every time a getter or a setter is called...
A #property is an instance variable that has had some semantic sugar applied to it, to help expose it to the outside world (usually), and to help avoid writing boilerplate code for getting and setting it.
though properties are made generally when you need to access some variable outside of the class, mean getter n setter, but in objective C, an additional need to make property is that the memory management goes on compiler ends, so if you are using some object, not primitive data types, then you should use property and synthesize it, and then release in dealloc if you are using manual reference counting. but again the main objective to make properties it to access some iVar outside the class like passing parameters from one class to other etc.
If you #synthesize a #property, you will have access to a get and a set method, which are very convenient. You can also define how the setter will behave (retain, assign, copy) if it's nonatomic or atomic and if it's read only. If you don't specify anything (aka you don't synthesize the property) the ivar won't be visible outside of the class by default, but you can achieve this by using #public. Logically you can also define them as #private or #protected .
Normally I #synthesize a #property because I want to have access to the ivar from the outside of the class and also because I want a getter and setter methods.
The general opinion is that you should use properties whenever possible. If you're still in doubt, here is Apple's recommendation:
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
...
You should always access the instance variables directly from within an initialization method because at the time a property is set, the rest of the object may not yet be completely initialized
Read the whole document here for a better understanding of the subject.
As for performance issues, for most apps the gain is insignificant. Read this for a very detailed description.
I am very much confused between instance variables and property. I have read number of posts regarding this but still i am not clear about it.
I am from JAVA background and what i infer from objective C documentation is that a property is similar to JAVA BEAN CLASS (one having getter and setter of instance varibles). A property can accessed from other classes through its getter and setter methods while an instance variable is private and cannot be accessed from other classes.
Am i right in thinking in this direction ?
The parallel with Java is very good. The only difference is that Objective C provides a way to access a property as if it were a variable, and Java does not. The other difference is that in Objective C you can synthesize properties, while in Java you need to write your getters and setters manually.
Property is a "syntactic sugar" over a getter method or a pair of a getter and a setter methods. Properties are often (but not always) backed by an instance variable, but they can be implemented in any way that you can implement a parameterless instance method.
Ok, instance variable and property is far away from each other. instance variable is a state of object and property is a assecor method(getter/setter) of that state(instance variable).
So whenever you create an property in header file. compiler convert those property in to accessor method. suppose you declared property - #property(nonatomic, assign, readwrite) NSString *name;
So compiler will be converted those in to
-(NSString *)name;
-(void)setName:(NSString *)name;
And then for definition for accessor method there is two way.
manually - use dynamic in implementation file(.m) and then give the definition of accessor method by doing this you won't get any warning.
Let compiler do the job - this can be done by synthesizing property e.g synthesize name;. so now compiler will generate the definition for the accessor method for you.
Hope it helps ;)
I know this subject has been beat to death here ... but some seem to be focusing on the technical details, whereas I wanted mention something along the lines of the BIG PICTURE ...
Think of properties as kind of first-class ivars. Both properties and ivars may model attributes of an object ... but an ivar gets special attention if you go ahead and set it up as a property. Basically, you should an attribute as a property (as opposed to an ivar) if you feel it needs getter / setter methods. Dot notation makes for very readable code. This may help in deciding when to declare a variable as a property as opposed to simply using a regular ivar.
A property in objective c is in fact the setter and getter methods that make it possible to access an attribute in a class from outside of it. So when you declare for example
#interface example:NSObject{
NSString *variable;
}
#property(readwrite, assign) NSString *variable;
#end
#implementation
#synthesize variable;
#end
You are in fact declaring the methods
-(NSString *)getVariable;
-(void)setVariable(NSString *)value;
And you can access then by using the point notation and the name of the property, like
instance.variable = something;
something = instance.variable;
The primary difference between instance variable and property is that for properties, the compiler will automatically generate a getter/setter method pair. For instance:
#property (nonatomic) int value;
will generate:
-(void)setValue:(int)i
{
value = i;
}
-(int)value
{
return self->value;
}
given #synthesized.
If you crab a book on Objective-C 1.0, you'll notice that this feature isn't available. This is a new feature in 2.0, also known as the dotted syntax. It's introduced mainly because the complicated getter/setter syntax.
The benefit of this feature is that even though you have the compiler automatically declared the pair for you, you can still manage to override it. For instance, you can still have -(void)setValue:(int)i declared as a method of your class, and override the behavior. This is useful in scenarios of validation, such as you want to put a limit on the range of value.
As far as Java is concerned, Objective-C actually do have #public instance variable syntax, but it's a habit not to use it. It's sort of similar to Java's concept of protecting a private variable through getter/setter. But its primary objective-c is to override getter/setter and minimize syntax.
Now this is just a preview, refer to http://cocoacast.com/?q=node/103 or some objective-c 2.0 books if you wanted to know more.
Well, maybe it was not clear that a property does not need an instance variable.
You can define a read-only property based on any calculation on instance variables or any other variables in the scope. The issue here is that you must manually code the getter.
#interface person:NSObject{
NSDate *birthDate;
}
#property(readonly) int age;
#end
#implementation
-(int) age{
// return calculated age based on birthDate and today;
}
#end
The name of the property does not need to be the same as the instance variable.
#synthesize myProperty = myVar;
I found this amazing thread which clearly explains each and evrything about properties.
http://www.iphonedevsdk.com/forum/iphone-sdk-tutorials/7295-getters-setters-properties-newbie.html
Thank you all for your responses.
I am puzzled by how is variable declared in objective C.
1: I see #property and #synthesize statement being used. My question regarding that is, what are these 2 statement for? Why are they always used together? I guess #synthesize is a shortcut to create the getter and setter?
2:Say, I want to declare an NSMutableArray that would be only be accessible inside the class that was declared in. I have to perform myArray = [[NSMutableArray alloc] init] before using the addObject method to write something to it. When do I release the array then?
3:Is there a different way to declaring a variable that is only accessible only at the class it was declared to being accessible at all classes?
4:Similar to question 2, but now the variable is an NSString. Why I don't have to alloc & init it to share the same variable within its own class? Whats the different between self.myString = #""; to myString = #"";
Thanks a lot.
For your first question:
#property (nonatomic, retain) NSString * someProperty;
This declares a property of the class. It becomes part of the public contract of the class but still lacks something important - actual implementation
#synthesize someProperty;
This is compiler sugar, its creates a getter and setter method for your property. To wit, this is the implementation that is needed in order to actually use your property in your class and from other classes.
You will in almost all situations, always have a #synthesize for each #property you declare.
For your second question:
You are correct about how to initialize your array property. In order to release it you would do the following in your classes dealloc method:
- (void) dealloc {
self.myarray = nil;
[super dealloc];
}
This effectively releases the array (assuming you declared your property with the keyword retain).
And for your last question:
Properties of a class are always available from other classes. In order to create a globally accessible variable you would declare it as static.
Ad 1: a property is a construct to control access an ivar (usually private) by getters and setters. Actually, a property doesn't even have to have a supporting ivar. Yes, #synthesize generates getter and setter (and ivar).
Ad 2: You release it when you don't need it anymore. When that is depends on the logic of your code.
Ad 3: If I understand that correcttly, you want #private ivars. Normally, ivars are protected, i.e. only accessible inside the class or in derived classes. Private ivars are only accessible inside the class itself. Properties are publicly accessible.
Ad 4: myString = #"" writes to the ivar directly, while self.myString = #"" uses the property setter.
You need to get a text on Objective-C or find an online tutorial -- it's a sufficiently arcane language that you can't hope to pick it up in dribs and drabs.
There are variables and there are properties -- two different things that intersect somewhat.
You can declare plain old instance variables the same way as in C/C++, more or less:
NSArray* myArray;
eg, placed in the {} enclosed section of the #interface.
But you can also have a PROPERTY, which you declare by saying #property in the #interface declaration (after the closing }). A property has a getter method -- by default called myProperty -- and a putter method -- by default called setMyProperty. If myProperty is the same name as one of your instance variables then you can use #synthesize to automatically create these methods.
Note that properties may be automatically retained when the default setter method is used. This is fairly convenient in terms of managing storage.
But managing storage is a big topic, one that you MUST read some good tutorial on -- we can't explain it in a few paragraphs.
1) #property declares a publicly accessible variable and associated getter and setter. #synthesize causes the compiler to automatically generate the definition (code) of the getter and setter.
2) You would declare the NSMutableArray in your class declaration, in the header file. You would initialize the variable in your init method, and you would release the variable in your dealloc method.
3) The variables created using #property are public. The variables defined in your class declaration (using #interface in the header file) can be declared as private to that class, using the #private keyword.
John, these questions are pretty basic. You would probably get a lot out of the Objective-C Programming Intro here ( http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html#//apple_ref/doc/uid/TP30001163 ).
This question already has answers here:
Closed 10 years ago.
I've previously avoided underscores in my variable names, perhaps a holdover from my college Java days. So when I define a property in Objective C this is what I naturally do.
// In the header
#interface Whatever
{
NSString *myStringProperty
}
#property (nonatomic, copy) NSString *myStringProperty;
// In the implementation
#synthesize myStringProperty;
But in almost every example it is done like
// In the header
#interface Whatever
{
NSString *_myStringProperty
}
#property (nonatomic, copy) NSString *myStringProperty;
// In the implementation
#synthesize myStringProperty = _myStringProperty;
Should I get over my aversion to the underscore because that is the one way it should be done, is there a good reason for this style being the preferred one?
Update: With automatic property synthesis nowadays you can leave out the #synthesize and the result is the same as if you'd used
#synthesize myStringProperty = _myStringProperty;
which clearly shows you Apple's preference. I've since learned to stop worrying and love the underscore.
I always use underscores. It creates a clear distinction between local variables and instance variables. It also avoids compiler warnings in the following situation:
#interface MyClass
{
NSString *name
}
#property (nonatomic, copy) NSString *name;
- (id) initWithName:(NSString *) name;
#end
#implementation MyClass
#synthesize name;
// The following method will result in a compiler warning
// (parameter name same as ivar name)
- (id) initWithName:(NSString *) name {
if (self = [super init]) {
self.name = name;
}
return self;
}
#end
EDIT:
After having to endure downvotes and reading through the comments, let me try to make my point:
Apple recommends that ivars have the same name as their property. Apple also recommends that properties start with a lowercase letter. And Apple also recommends that local variables start with a lowercase letter.
Now you have a problem, because when you read a piece of code, and you see a variable being used, you cant' tell by the naming convention if this variable is an ivar or a local variable. That sucks. The solution is to have different naming conventions for ivars and local variables. That's just plain common sense.
The way you implement this naming convention is irrelevant. If you really want, you can simply append "_WOOHAHA" to the ivar names. I don't care (but maybe others will). The thing is that people who know what they're doing have decided to go with the "underscore prefix" for ivars. IMHO, they made the right decision, even if their own company recommends something else. (the developers I'm talking about are the people writing some major Apple frameworks and the .NET Framework classes)
In the end, code quality is more important than following a stupid rule that isn't even followed by the people preaching it.
Another remark about the code you've shown: never use retain on string properties. You should use copy instead.
For more info about copy/retain on properties, see:
NSString property: copy or retain?
The naming convention for the instance variable prefixed by _ is now clearly stated by Apple in the "Coding Guidelines for Cocoa", after the revision of 2012-02-16, with its reason.
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 (_), for example:
#implementation MyClass {
BOOL _showsTitle;
}
If you synthesize the instance variable using a declared property, specify the name of the instance variable in the #synthesize statement.
#implementation MyClass
#synthesize showsTitle=_showsTitle;
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingIvarsAndTypes.html#//apple_ref/doc/uid/20001284-BAJGIIJE
The lecture in iTunes U, iPhone App Development CS193p Fall 2011 taught by Paul Hegarty at Stanford University, also explains this convention.
http://itunes.apple.com/itunes-u/ipad-iphone-application-development/id473757255
I'm aware of that this question is asked quite a while ago, but I myself had the same question and wanted to share my findings.
Current suggested Objective-C 2.0 practice is to use the same name for the ivar as the property. You can optionally assign a different ivar in the #property declaration, but the fact that by default, synthesized accessors for a property will access the ivar with the same name as the property indicates that's the pattern they expect you to follow.
No matter what, since objects still have to send messages to themselves to access properties, it's hard to confuse when you're accessing a property or when you're accessing its backing ivar directly, though using the 2.0 dot access to properties does make it more possible. Using the standard message passing syntax makes intent more explicit, IMO.
#interface Foo : NSObject {
NSNumber *bar;
}
#property(readwrite, retain) NSNumber * bar
#end
#implementation Foo
#synthesize bar;
-(void) baz {
NSNumber *numberOne = [NSNumber numberWithInt: 1];
//Both set the value of bar through either the your custom or the synthesized setter method
[self setBar:numberOne];
self.bar = numberOne;
//Both get the value of bar through your synthesized or your custom accessor method
NSNumber *fooBar = [self bar];
fooBar = self.bar;
//Both manipulate the bar ivar directly
bar = numberOne;
fooBar = bar;
}
#end
Apple reserves selectors beginning with underscore for their own "private" methods and that would include properties. I don't think they reserve _ for ivar names though.
Personally, I would steer clear of using underscore to start any kind of variable name. It's an opaque convention. What if somebody else uses underscore for locals and no underscore for instance variables? What if you accidentally omit the underscore in a method where you have a local defined with the same name?
It's much better to make your local names different from your ivar names. For example in a setter you might use newName or neWValue.
It is purely a style issue.
I don't know which examples use the underscored ivar style. The official Apple examples (e.g. CryptoExercise) do not prefix the ivars with _.
I will just point out that a new navigation project using core data uses trailing underscores by default and makes the variables private.
#interface MyTestAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navigationController;
#private
NSManagedObjectContext *managedObjectContext_;
NSManagedObjectModel *managedObjectModel_;
NSPersistentStoreCoordinator *persistentStoreCoordinator_;
}
#interface RootViewController : UITableViewController <NSFetchedResultsControllerDelegate> {
#private
NSFetchedResultsController *fetchedResultsController_;
NSManagedObjectContext *managedObjectContext_;
}
The KVC part of the runtime expects either a name or _name ivar when using valueForKey: on an object when it cant find a message to retrieve that variable. see http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/SearchImplementation.html
If the runtime bothers to search for _name and the apple documentation mentions the _name first there might be a good reason for this. Let's take a look at some SDK classes: UINavigationBar.h this class has underscores in front of all ivars, UIView too... the list goes on. Well maybe it is that way with the new fangled iOS SDK and good ole NS* classes don't do thinges that way... wrong; they use the underscore as well in the header files.
Apple uses the underscore in private API messages as well as ivars. I can't understand why their examples do not push this behavior especially when the runtime bothers to have this so called "naming convention" hard coded into the variable search path. It would be nice to see some consistency.
Just a note, there is a strict naming scheme you have to follow to be KVC compliant; the link above helps you to conform to this to use this handy feature of the runtime.