Sorry for the long read. This is a part of the book I'm confused on.
The current trend in coding conventions (which Xcode 4 has adopted) is
to use an underscore (_) as the leading character for an instance
variable name. So any references you see in the template code
generated by Xcode to variables starting with a _ are referencing the
instance variables directly by name. When you see an #synthesize
directive that looks like this
#synthesize window=_window;
Why couldn't _window be declared in #propterty/synthesize in the first place instead of assigning it to window?
it says to synthesize the getter and setter for the property named
window and to associate that property with an instance variable called
_window (which does not have to be explicitly declared). This helps to distinguish the use of the instance variable from the property and to
encourage you to set and retrieve the value of the instance variable
through the setter and getter methods. That is, writing something like
this
[window makeKeyAndVisible]; // This won't work
will fail, as there is no instance variable named window. Instead, you
have to either name the instance variable directly by its name, such
as
[_window makeKeyAndVisible];
or, preferably, use the accessor method:
[self.window makeKeyAndVisible];
Why does self.window not need the underscore when the other methods do?
You only access the underscore ivars within the setter/getter methods. In this case it would be within the implementations of - (UIWindow *)window and - (void)setWindow:(UIWindow *)window. Anywhere else in your class's implementation, refer to the #property and not the synthesized ivar (self.window). One thing that helped me understand in my early obj-c days was this: self.window = ...; is synonymous to [self setWindow:...]; Just follow the rules and you'll be one happy
Apple's internal implementation of Objective-C results in some extremely nifty memory management that you will never have to deal with as long as you abide by their rules. Typical Apple, but it works.
The syntax self.window is actually invoking a method (though it may not seem to). For instance if you #synthesize a #property named window or you define a method like - (id) window { ... } yourself, self.window will call that method and represent whatever value was returned. Similarly, self.window = value; implicitly calls [self setWindow:value] for you.
A #property can rename these default methods, e.g. using getter=.
Related
I have been unable to find any information on this topic and most of what I know about it has come by complete accident (and a few hours of trying to figure out why my code wasn't working). While learning objective-c most tutorials I have found make variables and properties with the same name. I don't understand the significance because it seems that the property does all the work and the variable just kind of sits there. For instance:
Test.h
#interface Test : NSObject {
int _timesPlayed, _highscore;
}
#property int timesPlayed, highscore;
// Methods and stuff
#end
Test.m
#implementation Test
#synthesize timesPlayed = _timesPlayed;
#synthesize highscore = _highscore;
// methods and stuff
#end
What I know
1) Okay so today I found out (after hours of confusion) that no matter how much changing you do to the properties highscore = 5091231 it won't change anything when you try to call [test highscore] as it will still be returning the value of _highscore which (I think) is the ivar that was set in test.h. So all changing of variables in test.m needs to be changing _highscore and not highscore. (Correct me if I'm wrong here please)
2) If I understand it correctly (I probably don't) the ivars set in test.h represent the actual memory where as the #properties are just ways to access that memory. So outside of the implementation I can't access _highscore without going through the property.
What I don't understand
Basically what I don't get about this situation is whether or not I need to use the ivars at all or if I can just use #property and #synthesize. It seems like the ivars are just extra code that don't really do anything but confuse me. Some of the most recent tuts I've seen don't seem to use ivars but then some do. So is this just a coding preference thing or is it actually important? I have tried searching through Apple's Documentation but I get rather lost in there and never seem to find what I'm looking for. Any guidance will be greatly appreciated.
You can think of the syntax for synthesizing properties as #synthesize propertyName = variableName.
This means that if you write #synthesize highscore = _highscore; a new ivar with the name _highscore will be created for you. So if you wanted to you could access the variable that the property is stored in directly by going to the _highscore variable.
Some background
Prior to some version of the compiler that I don't remember the synthesis statement didn't create the ivar. Instead it only said what variable it should use so you had to declare both the variable and the property. If you synthesized with a underscore prefix then your variable needed to have the same prefix. Now you don't have to create the variable yourself anymore, instead a variable with the variableName that you specified in the synthesis statement will be created (if you didn't already declare it yourself in which case it is just used as the backing variable of the property).
What your code is doing
You are explicitly creating one ivar called highscore when declaring the variable and then implicitly creating another ivar called _highscore when synthesizing the property. These are not the same variable so changing one of them changes nothing about the other.
Should you use variables or not?
This is really a question about preference.
Pro variables
Some people feel that the code becomes cleaner if you don't have to write self. all over the place. People also say that it is faster since it doesn't require a method call (though it is probably never ever going to have a measurable effect on your apps performance).
Pro properties
Changing the value of the property will call all the necessary KVO methods so that other classes can get notified when the value changes. By default access to properties is also atomic (cannot be accessed from more then one thread) so the property is safer to read and write to from multiple thread (this doesn't mean that the object that the property points to is thread safe, if it's an mutable array then multiple thread can still break things really bad, it will only prevent two threads from setting the property to different things).
You can just use #property and #synthesize without declaring the ivars, as you suggested. The problem above is that your #synthesize mapped the property name to a new ivar that is generated by the compiler. So, for all intents and purposes, your class definition is now:
#interface Test : NSObject {
int timesPlayed;
int highscore;
int _timesPlayed;
int _highscore;
}
...
#end
Assigning a value directly to the ivar timesPlayed will never show up if you access it via self.timesPlayed since you didn't modify the correct ivar.
You have several choices:
1 Remove the two ivars you declared in your original post and just let the #property / #synthesize dynamic duo do their thing.
2 Change your two ivars to be prefixed by an underscore '_'
3 Change your #synthesize statements to be:
#implemenation Test
#synthesize timesPlayed;
#synthesize highscore;
...
I typically just use #property and #synthenize.
#property gives the compiler and the user directions on how to use your property. weather it has a setter, what that setter is. What type of value it expects and returns. These instructions are then used by the autocomplete (and ultimately the code that will compile against the class) and by the #synthesize
#synthesize will by default create an instance variable with the same name as your property (this can get confusing)
I typically do the following
#synthesize propertyItem = _propertyItem;
this will by default create a getter and a setter and handle the autorelease as well as create the instance variable. The instance variable it uses is _propertyItem. if you want to access the instance variable you can use it as such.
_propertyItem = #"Blah";
this is a mistake tho. You should always use the getter and setter. this will let the app release and renew as needed.
self.propertyItem = #"Blah";
This is the better way to handle it. And the reason for using the = _propertyItem section of synthesize is so you cannot do the following.
propertyItem = #"Blah"; // this will not work.
it will recommend you replace it with _propertyItem. but you should use self.propertyItem instead.
I hope that information helps.
In your example, #synthesize timesPlayed = _timesPlayed; creates a new ivar called _timesPlayed and the property refers to that ivar. timesPlayed will be an entirely separate variable with no relation whatsoever to the property. If you just use #synthesize timesPlayed; then the property will refer to timesPlayed.
The purpose of the underscore convention is to make it easier to avoid accidentally assigning directly to an ivar when you want to be doing it through the property (i.e. through the synthesized setter method). However, you can still acces _timesPlayed directly if you really want to. Synthesizing a property simply auto-generates a getter and setter for the ivar.
In general you do not need to declare an ivar for a property, although there may be special cases where you would want to.
This may be an old question.. but in "modern times", #synthesize- is NOT necessary.
#interface SomeClass : NSObject
#property NSString * autoIvar;
#end
#implementation SomeClass
- (id) init { return self = super.init ? _autoIvar = #"YAY!", self : nil; }
#end
The _underscored backing ivar IS synthesized automatically... and is available within THIS class' implementation, directly (ie. without calling self / calling the automatically generated accessors).
You only need to synthesize it if you want to support subclass' ability to access the _backingIvar (without calling self), or for myriad other reasons, described elsewhere.
This question already has answers here:
Is there any reason to declare ivars if you're using properties exclusively in Objective-C?
(4 answers)
Closed 8 years ago.
I'm new to Objective-C, and I saw some open sourced code like below:
DetailedViewController.m:
#interface DetailedViewController()
#property(nonatomic, strong) UITableView *dynamicTable;
#end
#implementation DetailedViewControll
-(void)viewDidLoad
{
[super viewDidLoad];
self.dynamicTable=[[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
//configure dynamicTable
}
#end
if I declare the dynamicTable variable and use it as below:
#interface DetailedViewController()
{
// private tableview variable
UITableView *dynamicTable;
}
#end
#implementation DetailedViewControll
-(void)viewDidLoad
{
[super viewDidLoad];
dynamicTable=[[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
//configure dynamicTable
}
#end
I think the the above two ways of using dynamicTable variable are equal, Am I right?
if not, Does using property is better than using private variable?
Quote from Apple docs, explaining properties:
Practically speaking, properties reduce the amount of redundant code you have to write. Because most accessor methods are implemented in similar ways, properties eliminate the need to implement a getter and setter method for each property exposed in the class. Instead, you specify the behavior you want using the property declaration and then synthesize actual getter and setter methods based on that declaration at compile time.
In your case above two ways are equal. But if you want to use some advanced technics, such as Lazy Instantiation or Key-Value Observing, you'll definitely need properties.
Accessing a variable is faster than accessing a property. However, a property gives you some advantages like key-value observing (another object or your object can register to be notified once someone changes the value of the property). Which one to use is a matter of taste and use-case.
If you declare a property in your public .h file, other objects can access it. If you declare your variable in your public .h file, other objects can access it as well (object->variable) but this very, very bad, don't do that.
So strictly speaking, your two examples are not equal. They are, however, similar. Quite often it doesn't really matter which one you use. Use whichever suits you more. The fact that variable access is faster is not a good reason to chose one over the other except if you measured and know that a property is causing a performance problem (I have yet to see that, and I work on multimedia apps that need to be fast).
I'm was playing around with the standard sample split view that gets created when you select a split view application in Xcode, and after adding a few fields i needed to add a few fields to display them in the detail view.
and something interesting happend
in the original sample, the master view sets a "detailItem" property in the detail view and the detail view displays it.
- (void)setDetailItem:(id) newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
i understand what that does and all, so while i was playing around with it. i thought it would be the same if instead of _detailItem i used self.detailItem, since it's a property of the class.
however, when i used
self.detailItem != newDetailItem
i actually got stuck in a loop where this method is constantly called and i cant do anything else in the simulator.
my question is, whats the actual difference between the underscore variables(ivar?) and the properties?
i read some posts here it seems to be just some objective C convention, but it actually made some difference.
_property means you are directly accessing the property.
self.property means you are using accessors.
In your case, in the setter method you are calling it, creating a recursive call.
In the course of your experiment, you've set up an endless loop which is why the simulator goes non-responsive.
Calling self.detailItem within the scope of setDetailItem: calls setDetailItem: recursively since your class implements a custom setter method for the property detailItem.
I would refer you to the Apple documentation on declared properties for the scoop on properties, ivars, etc; but briefly, declared properties are a simplified way of providing accessor methods for your class. Rather than having to write your own accessor methods (as we had to do before Objective-C 2.0) they are now generated for you through the property syntax.
The properties are basically a way of the compiler to generate a setter and getter for a given instance variable.
So when you use something like:
id detailItem = self.detailItem;
what you are doing under the hood is:
id detailItem = [self detailItem];
Same for:
self.detailItem = otherDetailItem;
would be:
[self setDetailItem:otherDetailItem];
So when you write the setter yourself.. you get in an infinite loop since you access the method itself in itself.
You can freely make use of the 'self.' notation in your class, just not when you're overriding the setter or accessor because of the mechanism I described above.
Cases in a class where I use the . notation over simply accessing the ivar is when I change the value, you never know inside your class what needs to happen when you change the value. do you have something in terms of a status that should notify some delegate that a status changed? Usually this is not the case, however, just by using the . notation you are making sure that in the future you won't have to refactor some code if you did decide to do some magic in your setter method.
I'll make an example (without ARC enabled):
#property (nonatomic, retain) NSNumber* number;
If you don't synthesize it, you can access it this way:
self.number= [NSNumber numberWithBool: YES];
This case the number is retained.If instead you synthesize it and don't use the property:
#synthesize number;
Later in the file:
number=[NSNUmber numberWithBool: YES];
You haven't used the property, so the number is not retained.That makes a relevant difference between using accessors and synthesized properties.
While doing my project I was wondering if I should set my instance variables for a viewcontroller through the viewcontrollers #synthezied properties or creating a new init function that sets the instance variables when the init it called.
For me, it seems like setting the instance variables using the #properties are cleaner.
What do you think?
I dont use nibs or storyboards...
Synthesizing the properties just saves you from the trouble of writing setters and getters. Just using #synthesize does not initialize your properties. You should definitely initialize them - either in -init or when declaring them.
I'd go for designated initialiser approach as in set instance variables that then can be used via #synthesized properties. Initialising view controller and then setting its properties leave the object in an inconsistent state.
Designated initializer:
MyViewController * viewController = [[MyViewController alloc] initWithParam1:#"foo" param2:#5];
// now viewController is consistent as presumably it has all properties set
Setting properties via setters:
MyViewController * viewController = [[MyViewController alloc] init];
// here viewController is inconsistent as it does not have default properties set
[viewController setParam1:#"foo"];
[viewController setParam2:#5];
// only here viewController is consistent and can be used normally
Depending on implementation of your initialisers you may set default values for properties without passing them as params to initialiser too, so my second example may be faulty if init silently sets param1 to #foo and param2 to #5.
In general your designated initialiser should only have parameters that are strictly necessary. Anything optional usually goes elsewhere, such as being a readwrite #property. There's some amount of leeway here, at your discretion - sometimes you'll include an optional parameter because it is actually used the vast majority of the time (and when it's not it has an easy default, like nil or 0).
The idea being that any object returned by an init method should be usable in some fashion. Requiring additional steps to configure it is almost always indicitive of a poor design.
Following this principle also encourages immutable instances (since in many cases you can specify all the necessary parameters upfront), which are advantageous for many reasons - simplicity, predictability, thread-safety, copy-by-retain etc, etc.
For a view controller specifically, typically you would have an initialiser which takes the view to be controlled, and leaves everything else as #properties. Your view controller should work, in some capacity, with just the view set; all other properties should have reasonable defaults.
Being new to Objective-C (but a long term C/++) programmer I'm looking for advice/recommendations on naming conventions for variables.
My personal preference would be to utilize a prefix for instance variables both for clarity within functions and to prevent shadowing of function parameters. However I'm a fan of properties which rules out prefixes (unless you also prefix your property names, which doesn't work too well and looks daft). Similarly I could use the "self.variable" convention, but only if I make EVERYTHING a property.
So given the code below what's your preferred naming style for instance/function variables? And if you don't bother, how do you deal with shadowing on function params?
#interface GridItem : NSObject
{
CGRect _rect;
...
}
#end
-(void) initFromRect:(CGRect)rect
{
_rect = rect;
...
}
Cheers!
Most Cocoa projects use underbar as a non-IBOutlet instance variable prefix, and use no prefix for IBOutlet instance variables.
The reason I don't use underbars for IBOutlet instance variables is that when a nib file is loaded, if you have a setter method for a connected outlet, that setter will be called. However this mechanism does not use Key-Value Coding, so an IBOutlet whose name is prefixed with an underbar (e.g. _myField) will not be set unless the setter is named exactly like the outlet (e.g. set_myField:), which is non-standard and gross.
Also, be aware that using properties like self.myProp is not the same as accessing instance variables. You are sending a message when you use a property, just like if you used bracket notation like [self myProp]. All properties do is give you a concise syntax for specifying both the getter and setter in a single line, and allow you to synthesize their implementation; they do not actually short-circuit the message dispatch mechanism. If you want to access an instance variable directly but prefix it with self you need to treat self as a pointer, like self->myProp which really is a C-style field access.
Finally, never use Hungarian notation when writing Cocoa code, and shy away from other prefixes like "f" and "m_" — that will mark the code as having been written by someone who doesn't "get it" and will cause it to be viewed by suspicion by other Cocoa developers.
In general, follow the advice in the Coding Guidelines for Cocoa document at the Apple Developer Connection, and other developers will be able to pick up and understand your code, and your code will work well with all of the Cocoa features that use runtime introspection.
Here's what a window controller class might look like, using my conventions:
// EmployeeWindowController.h
#import <AppKit/NSWindowController.h>
#interface EmployeeWindowController : NSWindowController {
#private
// model object this window is presenting
Employee *_employee;
// outlets connected to views in the window
IBOutlet NSTextField *nameField;
IBOutlet NSTextField *titleField;
}
- (id)initWithEmployee:(Employee *)employee;
#property(readwrite, retain) Employee *employee;
#end
// EmployeeWindowController.m
#import "EmployeeWindowController.h"
#implementation EmployeeWindowController
#synthesize employee = _employee;
- (id)initWithEmployee:(Employee *)employee {
if (self = [super initWithWindowNibName:#"Employee"]) {
_employee = [employee retain];
}
return self;
}
- (void)dealloc {
[_employee release];
[super dealloc];
}
- (void)windowDidLoad {
// populates the window's controls, not necessary if using bindings
[nameField setStringValue:self.employee.name];
[titleField setStringValue:self.employee.title];
}
#end
You'll see that I'm using the instance variable that references an Employee directly in my -init and -dealloc method, while I'm using the property in other methods. That's generally a good pattern with properties: Only ever touch the underlying instance variable for a property in initializers, in -dealloc, and in the getter and setter for the property.
I follow Chris Hanson's advice in regards to the underscore ivar prefix, though I admit I do use underscore's for IBOutlets as well. However, I've recently starting moving my IBOutlet declarations to the #property line, as per #mmalc's suggestion. The benefit is that all my ivars now have an underscore and standard KVC setters are called (i.e. setNameField:). Also, the outlet names don't have underscores in Interface Builder.
#interface EmployeeWindowController : NSWindowController {
#private
// model object this window is presenting
Employee *_employee;
// outlets connected to views in the window
NSTextField *_nameField;
NSTextField *_titleField;
}
- (id)initWithEmployee:(Employee *)employee;
#property(readwrite, retain) Employee *employee;
#property(nonatomic, retain) IBOutlet NSTextField *nameField;
#property(nonatomic, retain) IBOutlet NSTextField *titleField;
#end
You can use the underbar prefix on your ivars and still use the non-underbar name for your properties. For synthesized accessors, just do this:
#synthesize foo = _foo;
This tells the compiler to synthesize the foo property using the_foo ivar.
If you write your own accessors, then you just use the underbar ivar in your implementation and keep the non-underbar method name.
Personally, I follow the Cocoa naming conventions, using camel-casing for functions and variables, and capitalized camel-casing for object names (without the leading NS of course).
I find type prefixing makes code more opaque to anyone who didn't write it (since everyone invariably uses different prefixes), and in a modern IDE it's not really that difficult to figure out something's type.
With the introduction of properties I see no need for prefixing "_" to class instance variables. You can set a simple rule (described in your header file) that any variables to be accessed external to the class must be accessed via the property, or by using custom methods on the class to affect values. This to me seems much cleaner than having names with "_" stuck on the front of them. It also properly encapsulates the values so that you can control how they are changed.
I don't like using underscores as prefixes for any identifiers, because C and C++ both reserve certain underscore prefixes for use by the implementation.
I think using "self.variable" is ugly.
In general, I use unadorned identifiers (that is, no prefixes nor suffixes) for instance variables. If your class is so complicated that you can't remember the instance variables, you're in trouble. So for your example, I'd use "rect" as the name of the instance variable and "newRect" or "aRect" as the parameter name.
Andrew: There actually are plenty of Cocoa developers who don't use instance variable prefixes at all. It's also extremely common in the Smalltalk world (in fact, I'd say it's nearly unheard-of in Smalltalk to use prefixes on instance variables).
Prefixes on instance variables have always struck me as a C++-ism that was brought over to Java and then to C#. Since the Objective-C world was largely parallel to the C++ world, where as the Java and C# worlds are successors to it, that would explain the "cultural" difference you might see on this between the different sets of developers.
My style is hybrid and really a holdover from PowerPlant days:
THe most useful prefixes I use are "in" and "out" for function/method parameters. This helps you know what the parameters are for at a glance and really helps prevent conflicts between method parameters and instance variables (how many times have you seen the parameter "table" conflict with an instance variable of the same name). E.g.:
- (void)doSomethingWith:(id)inSomeObject error:(NSError **)outError;
Then I use the bare name for instance variables and property names:
Then I use "the" as a prefix for local variables: theTable, theURL, etc. Again this helps differentiate between local and and instance variables.
Then following PowerPlant styling I use a handful of other prefixes: k for constants, E for enums, g for globals, and s for statics.
I've been using this style for something like 12 years now.
While I love using the underscore prefix for ivars, I loathe writing #synthesize lines because of all the duplication (it's not very DRY). I created a macro to help do this and reduce code duplication. Thus, instead of:
#synthesize employee = _employee;
I write this:
ddsynthesize(employee);
It's a simple macro using token pasting to add an underscore to the right hand side:
#define ddsynthesize(_X_) #synthesize _X_ = _##_X_
The only downside is that it will confuse Xcode's refactoring tool, and it won't get renamed, if you rename the property by refactoring.
Along with what's been said here, be sure to read the Cocoa documentation on Key Value Observing compliant naming. Strictly following this pattern will help you greatly in the long run.