Prefixing property names with an underscore in Objective C [duplicate] - iphone

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.

Related

When do I need to have both iVar and a property?

I see some examples sometimes would declare a property as well as variable other times they do not .e.g. some time I see code like this
#interface Test : NSObject
{
UIProgressView* _progressView;
}
#property (nonatomic,retain)UIProgressView* progressView;
#end
at other times I will come across
#interface Test : NSObject
#property (nonatomic,retain)UIProgressView* progressView;
#end
Why what are the reasons ? I am learning and almost always use property and variable both.
I have used UIProgressView just as example.
Using ivars instead properties is only useful if you want #protected access (access from subclasses only), or support the old runtime (which required both).
It depends whether the property is synthesized against an iVar or derived in some other way (or against another iVar).
IF we have an instance of the class - i.e:
Test *myTest = [[Test alloc] init];
Then basically the property declaration
#property (nonatomic,retain)UIProgressView* progressView;
is telling anyone interested in using the interface that they can access the following two functions on an instance of this class:
[myTest progressBar];
[myTest setProgressBar:aProgressBar];
And objective C also lets you use shorthand notation:
myTest.progressBar =
xxx = myTest.progressBar
which does exactly the same thing.
It is not necessary for these two methods to be implemented via an iVar of the same name as the property, or even via an iVar at all (they could do even do a database fetch or derive the value).
If you #synthesize the property (which means you want the precompiler to generate the above methods for you) and don't explicitly specify an iVar on the #synthesize directive, then the methods described above will automatically be generated (due to the synthesize method) to set or get the value to/from an iVar of the same name as the property (and the implementation will include retain/release logic depending on the property directive.
If you don't #synthesize the property then you provide your own implementation and it can be anything you want. It is also possible to #synthesize the property but include a directive to use a different iVar in the method definition:
#synthesize progressBar=someOtheriVar;
in which case you will not see an iVar of the same name as the property in the header file either.

Basic objective C variable declaration

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 ).

Is a private synthesized property an oxymoron?

After going through a beginner's iPhone developer book and reading sample code online, I've noticed that most Objective C programmers synthesize nearly every instance variable. Some variables are convenient to snythesize, but most should not when honoring the object oriented principle of encapsulation. The worst are synthetized properties marked as private. A C++ programmer trying to use someone else's code will read the public fields and methods in the header file. They will skip the private variables. This C++ programmer will not know that you intended the private properties to be used in some meaningful way.
Take a look at this sample template on lazy table image loading provided by Apple:
Header
#interface ParseOperation : NSOperation <NSXMLParserDelegate>
{
#private
id <ParseOperationDelegate> delegate;
NSData *dataToParse;
NSMutableArray *workingArray;
AppRecord *workingEntry;
NSMutableString *workingPropertyString;
NSArray *elementsToParse;
BOOL storingCharacterData;
}
Source
#interface ParseOperation ()
#property (nonatomic, assign) id <ParseOperationDelegate> delegate;
#property (nonatomic, retain) NSData *dataToParse;
#property (nonatomic, retain) NSMutableArray *workingArray;
#property (nonatomic, retain) AppRecord *workingEntry;
#property (nonatomic, retain) NSMutableString *workingPropertyString;
#property (nonatomic, retain) NSArray *elementsToParse;
#property (nonatomic, assign) BOOL storingCharacterData;
#end
#implementation ParseOperation
#synthesize delegate, dataToParse, workingArray, workingEntry, workingPropertyString, elementsToParse, storingCharacterData;
Now I know this is not C++ and we shouldn't assume all C++ practices should be honored in Objective C. But Objective C should have good reasons to stray away from general programming practices.
Why are all the private ivars synthesized? When you look at the project as a whole, only NSMutableArray *workingArray is used by outside classes. So none of the other ivars should have setters and getters.
Why are very sensitive ivars synthesized? For one, now that id delegate has a setter, the user of this object can switch the delegate in middle of the XML parsing, something that doesn't make sense. Also, NSData *dataToParse is raw XML data retrieved from the network. Now that it has a setter, the user of this object can corrupt the data.
What's the point of marking everything private in the header? Since all ivars are are synthesized to have getters/setters, they are effectively public. You can set them to anything you want and you can get their value whenever you want.
I follow the idiom modeled by this example in many of my classes, so I can try to explain my own justification for this practice.
The properties in this example are declared in a class extension in the .m file. This makes them effectively private. Any attempt to access these properties from another class will cause a "Property not found" error upon compilation.
For developers coming from other languages, it may seem strange to synthesize getters and setters for private instance variables. Indeed, there is only one reason why I do this. When used consistently, synthesized properties can simplify memory management and help avoid careless mistakes that can lead to bugs. Here are a couple of examples:
Consider this:
self.workingPropertyString = [NSMutableString string];
versus this:
workingPropertyString = [[NSMutableString string] retain];
Many developers would claim that these two assignments are functionally equivalent, but there's an important difference. The second assignment leaks memory if workingPropertyString was already pointing at a retained object. To write code functionally equivalent to the synthesized setter, you'd have to do something like this:
NSMutableString *newString = [NSMutableString string];
if (workingPropertyString != newString) {
[workingPropertyString release];
workingPropertyString = [newString retain];
}
This code avoids leaking any existing object that the instance variable may be pointing to, and it safely handles the possibility that you may be re-assigning the same object to the instance variable. The synthesized setter does all of this for you.
Of course we can see that (workingPropertyString != newString) will always be true in this case, so we could simplify this particular assignment. In fact in most cases you can probably get away with a simple direct assignment to an instance variable, but of course it's the exceptional cases that tend to create the most bugs. I prefer to play it safe and set all my object instance variables through synthesized setters. All my instance object assignments are simple one-liners that look like this:
self.foo = [Foo fooWithTitle:#"The Foo"];
or this:
self.foo = [[[Foo alloc] initWithTitle:#"The Foo"] autorelease];
This simplicity and consistency gives my feeble brain less stuff to think about. As a result I almost never have bugs related to memory management. (I'm aware that the autorelease idiom could theoretically consume excessive memory in a tight loop, but I have yet to encounter that issue in practice. If I ever do, it's a simple case to optimize.)
One other thing I like about this practice is that my dealloc methods all look like this:
- (void)dealloc {
self.delegate = nil;
self.dataToParse = nil;
self.workingArray = nil;
self.workingEntry = nil;
self.workingPropertyString = nil;
self.elementsToParse = nil;
[super dealloc];
}
EDIT: Daniel Dickison pointed out some
risks to using accessors in dealloc
that I hadn't considered. See the
comments.
where every object property is simply set to nil. This simultaneously releases each retained property while setting it to nil to avoid certain crashes due to EXC_BAD_ACCESS.
Note that I've set self.delegate = nil; even though that property was declared as (nonatomic, assign). This assignment wasn't strictly necessary. In fact, I could do away with properties for my (nonatomic, assign) objects altogether, but again I've found that applying this idiom consistently across all my instance variables gives my brain less to think about, and further reduces the chance that I'll create a bug through some careless mistake. If necessary I can simply flip a property from (nonatomic, assign) to (nonatomic, retain) without having to touch any memory management code. I like that.
One could also use consistency as an argument for synthesizing properties for private scalar variables, as your example has done in the case of BOOL storingCharacterData;. This practice ensures that every instance variable assignment will look like self.foo = bar;. I don't usually bother to create private scalar properties myself, but I can see some justification for this practice.
Why are all the private ivars
synthesized? When you look at the
project as a whole, only
NSMutableArray *workingArray is used
by outside classes. So none of the
other ivars should have setters and
getters.
No real need; if you are going to access all the ivars directly anyway, there is no need for #synthesize.
Why are very sensitive ivars
synthesized? For one, now that id
delegate has a setter, the user of
this object can switch the delegate in
middle of the XML parsing, something
that doesn't make sense. Also, NSData
*dataToParse is raw XML data retrieved from the network. Now that it has a
setter, the user of this object can
corrupt the data.
None of the setter/getters are publicly declared. If a client of the class wanted to corrupt things by switching the delegate in the middle, they'd have to break encapsulation to do so.
So, ultimately, a non-issue.
What's the point of marking everything
private in the header? Since all ivars
are are synthesized to have
getters/setters, they are effectively
public. You can set them to anything
you want and you can get their value
whenever you want.
Note that there is no need to even declare the ivars in that example; the compiler will automatically synthesize them based on the #property declaration.
Traditionally, #private protected against someone diddling the ivar directly from externally to an instance of the class.
Note that anInstance->ivar or self->ivar is almost never used (and, when used, it is almost always for the wrong reason). There are uses for it, but it is rare.

AVFoundation - property declarations - basic question

I'm fiddling around with the AVCamDemo from Apple. Apart from trying to get my head around all that, I ran into something I don't understand.
The properties are initialized in a very strange way and I didn't find any explanation for this.
In the header-file
AVCaptureSession *_session;
...
#property (nonatomic,readonly,retain) AVCaptureSession *session;
in the .m-file
#synthesize session = _session;
What's the story with the underscore???
Thanks for any clarification!
Basically, you have two things going on here. an ivar (instance variable) and the property.
The ivar is the actual variable.
The property is syntactical sugar for getters and setters.
If you do
#synthesize session;
The ivar and the property are assumed to have the same name by the compiler.
if you do
#synthesize session = _session;
Then the property name is session and the ivar name is _session.
MY OPINION:
I've been doing Cocoa for over a decade. and #synthesize session = _session; is the safer way. Every now and then, the compiler or the programmer get confused when the ivar and the property have the same name.
The underscore is a naming convention to distinguish properties from instance variables.
In particular, it helps to distinguish between assignment to the property (that automatically decreases and increases the reference count) and assignment ot the instance variable (without automatic reference count update).

Confusion with header and Implementation files in Objective-C

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.