I am fairly far along developing a reasonably ambitious first iPhone project and I am confused as to which way to implement and access properties and why.
Example 1:
(in the .h)
Nsstring *_sale;
#property (nonatomic, retain) NSString *sale;
(in the .m)
#synthesize sale = _sale;
Example 2:
(in the .h)
#property (nonatomic, retain) NSString *sale;
(in the .m)
#synthesize sale;
Both of these seem to work to me without trouble but I am trying to figure out why there are two ways to do this and what benefits there may be to either.
Can someone tell me the difference?
Example 1 demonstrates the old way of defining ivar/property variable pairs. The new compiler now generates ivars (the NSstring *_sale; part) for you. Example 1 also demonstrates manually pairing up the property sale to the ivar _sale using the #synthesize sale = _sale; statement.
Example 2 is a more concise way to implement properties in Obj-C and is the way you will see most example code on the internet. The vast majority of the time you can write your properties without needing to overwrite the accessor/mutator methods generated for you by the compiler.
There are some die-hard proponents of the underscore prefix to denote instance variables for clarity's sake. You may find that this helps you when it comes to memory management, as in Example 1, setting self.sale equal to an autoreleased NSString would be fine since it would get retained, but setting _sale equal to an autoreleased object would result in erratic behavior later on because the NSString passed in would not be retained by the instance variable.
In general, I prefer writing my properties as you have shown in Example 2.
Short Answer: There are two ways of doing this because the new compiler now can infer some stuff for you, but the previous way of doing things has been left in for backwards compatibility.
They both work the same way. Some people prefix their instance variable with an underscore as a visual cue to differentiate member variables from instance variables.
More discussion at this SO question: How does an underscore in front of a variable in a cocoa objective-c class work?
For more Cocoa style guidelines checkout CocoaDevCentral.
Related
I'm fairly new to C and Objective-C, having been taught Python beforehand. As such, there are things about the C family that boggle my mind. I've looked around the web, gotten books, and browsed the forums here, but some things are still bugging me...
I understand variables vs. pointers in theory (one returns a value, and the other returns the address of the value in the system.) What I don't understand is when it's appropriate to use one over the other. Any advice?
When declaring a class, what is a property? It seems like properties and class variables are identical, yet I know there must be some critical difference.
#interface testViewController : UIViewController {
IBOutlet UILabel *label;
IBOutlet UIImageView *uiImageView;
}
#property (nonatomic, retain) IBOutlet UILable *label;
#property (nonatomic, retain) IBOutlet UIImageView *uiImageView;
#end
If possible, although unlikely, could you answer with a comparison to Python? I know Objective-C and Python are night and day, but whatever you can think of would be great.
The books I got were from Apress: Learn C on the Mac, Learn Objective-C on the Mac, and iPhone and iPad Apps for Absolute Beginners.
I really do appreciate any help!
I understand variables vs. pointers in theory (one returns a value, and the other returns the address of the value in the system.) What I don't understand is when it's appropriate to use one over the other. Any advice?
Unlike Java, Python and .NET where all variables are "pointers to objects" that can be passed around, in C things can exist in two places.
In the program code (variable appears when code is hit, disappears when function returns). Like this:
int my_arr[3];
or, on the "heap" which is memory not a part of the program which is requested dynamically like this:
int *my_arr_pointer = malloc(sizeof(int) * 3);
The second example is close to how Java, Python and .NET pass things around. However when you use malloc() to get memory, you need to use free() on it later...or your program sucks up and wastes the computers memory. So use technique to ensure you use a consistent amount of memory. Use the second to write a more flexible application. C doesn't have memory management which is why the first approach makes a faster, easy to debug program... that requires copying things between functions compared to the second approach where it's easier to have a flexible sized array where the program grows and shrinks in size... but it's slightly more complex to write. Use what is appropriate.
3 .When declaring a class, what is a property? It seems like properties and class variables are identical, yet I know there must be some critical difference.
Properties are wrappers to class variables. A "setter" and a "getter". This allows you to:
a) use a breakpoint to find out where in your code that variable is being set.
b) to check security, or permissions, or to validate the value being set.
c) A property doesn't have to tie to a variable. It can create an "illusion" of it, when the data is dynamically generated. e.g a size property might count the letters in the string when you ask for it, rather than storing it.
d) more flexibility to change the class later without having change everything accessing that property.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What describes #property(…) best? What's that actually good for?
If I declare a variable in my class interface, I can use such variable anywhere on my class. Awesome.
If I use #property (retain) Something *myVar; I can access that variable with self.myVar... But, what is the difference? Is there a good reason I should use one method or another?
Short answer: Encapsulation of memory management.
Longer answer: You need to establish ownership of an object if you want to use it later. If you want to use it later, you'll need a reference to it with which to do so, and a great place to keep that reference is in an instance variable.
You could handle the ownership claims (i.e. retains and releases) each time you assign a new value to that, but that would leave a lot of repetitious and trouble-prone boilerplate code scattered all over the place, like cherries in a fruitcake. That kind of mess is fiendishly difficult to debug when (not if) something goes wrong. So, it's far better to wrap that code up in accessor methods, so you can write it once and then forget about it.
But accessor methods are mostly boilerplate too, so we use #property declarations to create them automagically, rather than writing them by hand.
Edit: Apple's Memory Management Guide provides a lot of detail about what the accessor methods generated by #property do behind the scenes.
If I use #property (retain) Something *myVar; I can access that variable with self.myVar... But, what is the difference?
#property (retain) Something *myVar;
// this property declaration declares:
- (Something *)myVar;
// and
- (void)setMyIvar:(Something *)arg;
// and is accessible by dot syntax.
// it also declares and/or documents how the ivar is managed (copy, retain, etc.)
in use:
// direct access to the ivar. zero additional overhead (with regard to accessing the ivar)
[myVar message];
// properties used with dot syntax invoke the accessor. therefore,
[self.myVar message];
// is the same as:
[[self myVar] message];
the property's properties also give instructions to the compiler as to how to synthesize an accessor.
Is there a good reason I should use one method or another?
in init and dealloc, access the ivar directly - you are interested in initialization and cleanup of the object's ivars and do not care about subclasses. using properties here can also introduce bugs or undefined behavior.
for other cases, that is, when the object is in a fully constructed state, you should always use the accessor for consistency. if a subclass overrides an accessor, direct access of the ivar could break designs.
if you want to avoid this, then make the ivar private and do not declare a property for it. if you do declare a property for it, then document that it is private; i'll typically write #property (retain) Something * private_myIvar; in this case. in this case, it is convenient to use a property to synthseize the ivar's memory management.
when the ivar is private, you have total access to it. it is safe to access directly or by private property. otherwise, assume that you must use the accessor.
if myIvar is declared private and will be created only at initialization, you can avoid declaring the properties altogether. this will reduce runtime overhead (if that is critical). messaging overhead, retain/release cycles, and atomics will (naturally) require more execution time. so it can be bypassed to improve performance.
visibility/maintenance. sometimes, it's far less maintenance/implementation to hide an ivar from the interface. in other cases, the ivar is an implementation detail of the class, and should not be a part of the public interface. in such cases, consider making it private (there are a few ways to accoomplish this in objc).
Using the #property to access your ivars, does a lot of the repetitive code of releasing and retaining objects for you. You don't have to use them. It's just a lot of tutorials make it simple for people that are new to the platform.
In my code, every time I need a new object attribute for my class, I typically copy/paste its name in 4 different places!
The declaration in the header file (NSObject * myObject;)
The #property() line
The #synthesize() line in the implementation
Releasing it under dealloc: (only for objects of course)
I do this because it works, not because I completely understand what's going on. I do know that the declaration in the header file allows other classes to see its attributes, the property specifier determines how its getter/setter methods will be constructed. And the synthesize line actually builds those getter/setter methods. I also know that primitive types should use (nonatomic,assign) instead of (nonatomic,retain), but I have no clue when I should omit the nonatomic.
What can I do to avoid redundancy in my code. If I change or add a variable in my class I have to check 4 different places, and it gets old really fast. Are there any key strokes to make this process faster? Are there lines of code I can simplify or combine to obtain the same result?
Accessorizer will automate a lot of this for you.
In the latest version of Clang (Ships with XCode 4, not in XCode 3 yet) you get default #synthesize as well as default ivar creation. The default ivar creation already works, but not on the simulator. With both of these features all you need to do is add the #property line and deal with the memory management in dealloc
As far as nonatomic vs atomic. atomic is the default, and what happens when you leave off the nonatomic annotation. Atomic guarantees that the value is completely set before allowing anything to access it, nonatomic doesn't. Atomic is only useful in threading situations, and is slightly slower in singlethreaded applications.
It's important to understand what each of those lines of code does. They are not all the same and they are not necessarily redundant. One thing that will help is to use the correct terminology — for example, with NSObject *myObject; you're probably referring to an instance variable declaration.
First and foremost, a #property declaration in an #interface lets you say that instances of a class expose a piece of state. It doesn't say much about the implementation of that state, only that it's exposed by instances of your class and the API contract (memory management, atomicity, methods) for the state.
The #synthesize directive tells the compiler to create or use a specific instance variable as storage for a declared #property. This does not need to be how you provide storage for a property. For example, Core Data provides its own storage for modeled properties, so you use #dynamic for those instead. You also don't need to use an instance variable with the same name as your #property — to extend your example above, you might name your instance variable myObject_ while naming your property object and that's perfectly fine.
Finally, you send the instance variable -release in -dealloc — for an object-type property marked retain or copy — because you've said you'll manage its memory. You're not releasing the property, you're releasing the storage. If you implemented the storage some other way, you'd clean it up some other way.
I'm diving into iOS development and I find that for each of my UI controls, I always just blindly declare their #property like so, since that's how it was done in some tutorial I read when I started learning...
#property (retain, nonatomic) IBOutlet UILabel *lblStatus;
I'm still getting familiar with these attribute types and what they mean, but I find these two attributes allow me to accomplish my goals. Would I ever want to use any #property attributes other than "retain" and "nonatomic" for UI variables?
Thanks in advance for all your help!
NOTE: This answer is more relevant to UI Items in general.
Yes there is other situation where you would want to use the "assign" macro instead of "retain" (Assign is default for now but you get warning at compile-time if you don't specify it explicitly)
Apple gives a good example of this on one of their tutorial: Advanced UITableViewCell
They only "assign" in order to avoid cycle retains. (each of the view retains the other so they can't be deallocated).
NOTE: I missed the reference to UI variables in the question, so this answer is a more general discussion.
Yes, you will definitely need to use other attributes than those two, although that combination is the most common one.
copy - Use this in situations where you don't want as subsequent change to the data to be "picked up" by your class. In other words, when you want full control of the data once it's passed in. Sometimes this is desirable, sometimes not. Classes like NSString and UIColor are often used through properties with the copy attribute. My answer here gives a little bit more background.
assign - You use this with primitive types like int. You can't retain or copy an int or a float, because they are not objects, so you have to use assign. (Also, you don't have to, and can't, release those variables in your dealloc method.) This is true also for C structs, which are not covered by the Objective-C retain count system.
assign special case - sometimes you use assign even with objects, because you want to avoid retain cycles. Look at the header for UITableViewfor example. You'll notice that the delegate property is declared like this: #property(nonatomic, assign) id<UITableViewDelegate> delegate . Delegate properties should always be declared with assign and the same applies in some other situations, although you are not likely to run into them very soon.
nonatomic - This tells the compiler that the property is intended only to be accessed from one thread, and therefore it can omit some code that would otherwise slow down your program (potentially considerably). So the rule here is: if the property will, or might, be accessed from several threads, you should not declare it to be nonatomic (atomic is the default). Note however that making properties atomic is in no way sufficient to make your code thread safe. That's another, and much much thornier, topic.
The answer is NO. The reason behind this is the reason why we are using nonatomic and retain. From memory management guide "Objects in the nib file are created with a retain count of 1 and then autoreleased. As it rebuilds the object hierarchy, UIKit reestablishes connections between the objects using setValue:forKey:, which uses the available setter method or retains the object by default if no setter method is available. This means that (assuming you follow the pattern shown in “Outlets”) any object for which you have an outlet remains valid." So we are providing this setter just to make a match with the default behavior. Yes, it is possible to declare the setter in other ways but at least I have not found no reason to do so. If we use assign instead of retain, then there is no guarantee that the objects will remain valid. And memory management is already critical in iPhone and obviously I don't want to make it further critical by ignoring the convention. -- edit The answer NO is only for UI variables, that is for IBOutlets. Don't be confused. Other attributes are necessary in other cases as explained in other answers.
(retain) is generally used for instance variables and assign will go for delegates and primitive data types like bool , int
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.