Objective-C properties - is using [self myProperty] or self.myProperty slower than myProperty? - iphone

I'm using Objective-C properties to handle retaining/releasing instance variables for me. In my class, i'm doing stuff like this:
self.myProperty = somethingIWantToRetain
[self.myProperty doSomeAction]
[self.myProperty doSomethingElse]
Is using [self myProperty] / self.myProperty slower than simply using myProperty for those lines where i'm not changing the value of myProperty? Eg would the following be faster?
self.myProperty = somethingIWantToRetain
[myProperty doSomeAction]
[myProperty doSomethingElse]
Thanks

It's almost certainly a little bit slower, but it's unlikely to matter much.
Referring to your ivar directly (with a naked myProperty) accesses the variable directly. Referring to your property getter (with the equivalent self.myProperty or [self myProperty]) has to invoke a method, which will generally perform a retain and autorelease on your ivar.
However, method dispatch in Objective-C is very, very fast, and the retain/autorelease calls are pretty cheap as well, especially for objects that will likely not be destroyed when the autorelease pool is cleared. I would focus on readability and consistent style, and only worry about performance here when it becomes clear that you have performance bottlenecks to chase.

To be precise, when you write [myProperty doSomeAction], you are not actually accessing the property, but accessing the instance variable (used as the backing variable of the property) directly.
You only access the property (thru its setter and getter) with the dot-notation [self.myProperty doSomeAction] (or by calling the setter/getter explicitly like [[self myProperty] doSomeAction] which is an exact equivalent, as this is what the compiler translates to when compiling your code)
So when you write [myProperty doSomeAction], as it access the variable directly — contrary to [self.myProperty doSomeAction] which calls the getter of myProperty thus making an additional method call / message send — then yes in theory it will be faster as you will gain one message dispatch.
But in practice you won't see any improvement, so there is no need to consider accessing the variable directly (and it will make you loose flexibility if you want to implement it another way later)
Moreover, if you use the Modern Runtime (which is the case if you code for any version of iOS, Legacy Runtime being only used in 32-bits Mac OSX), then explicitly defining the backing variable for the property is not needed anymore. Thus you can declare the #property in the .h and #synthesize it in the .m without any instance variable (the compiler will generate it for you at compile time), and in such case you won't be able to call the (non-existing) instance variable! (at least not before the #synthesize directive)

Using Objective-C 2.0 dot syntax is equivalent to calling the getter, so the first snippet would be slower on the basis that you'll incur two additional dynamic dispatches.
That being said, the loss will be minor and obviously you'll gain the flexibility of being able to change the setter and getter at a later date (such as if you end up making that value implicit such that it's not technically stored in memory, or passing it off to a third object, or doing something asynchronous to store that may require you to block on the getter in some circumstances).

Slower as in one more step in operation? Yes.
Slower as in noticeably or realistically slower? Absolutely not.
You have to remember that modern cpus run programs at several million operations per second. In virtually all languages, calling a getter method is essentially the same speed as accessing the ivar itself (especially when there's no other code in the getter method).
It's good habit to use getters rather than accessing the ivars directly though, so I wouldn't try to "speed things up" by ignoring them.

Yes, it would be marginally faster, but it's unlikely that you'll improve performance noticeably by doing this kind of micro optimization. If you use self.myProperty, you could later decide to implement a different accessor method without having to change your code everywhere.

Related

On benefits of using ivar variables instead of getters

Though i am using Objective-C syntax, the question language agnostic.
Assuming the following declaration
#synthesize activities = _activities;
self.activities will call the getter and _activities will check for the value which was already assigned. The main benefit of this assignment, as i understand it, is to clearly differentiate when setter is called and when local variables is called instead.
While this is nice, what is the real tangible benefit of using ivar vs using getter methods?
I can think of one, what are others?
I suppose using ivar is faster then calling the getter, but compared with what goes on with touch events, the difference is negligible.
Accessing the instance variables directly means circumventing any atomicity protection and memory management supplied by the synthesized accessors. If it's clear when you're doing that, it's easier to audit such access to ensure that you're looking after these aspects of the class's behaviour yourself.

Why Use Properties?

So I've been programming on Objective-C for over a year now, and I can't seem to understand the use for properties. I have searched the internet a few times but never really found a good explaniation. I understand how to create them:
#property (something, something) something *variableName;
#syntheize variableName;
But should I make all my instance variables properties. To me, from what I know, it seems like a waste of code. But when I look at code online, sometimes I see like 25 properties in one class. Which I think is a waste. The only time I ever use them is when passing info from a UITableView cell selected to a detail viewController. For that, I use:
#property (copy) NSString *myString;
Can you also explain what: nonatomic, copy, retain, assign, etc. mean.
Thanks
These properties are convenience methods for creating getters and setters.
Atmoic v Nonatomic
Assuming that you are #synthesizing the method implementations, atomic vs. non-atomic changes the generated code. If you are writing your own setter/getters, atomic/nonatomic/retain/assign/copy are merely advisory.
With atomic, the synthesized setter/getter will ensure that a whole value is always returned from the getter or set by the setter, regardless of setter activity on any other thread. That is, if thread A is in the middle of the getter while thread B calls the setter, an actual viable value -- an autoreleased object, most likely -- will be returned to the caller in A.
In nonatomic, no such guarantees are made. Thus, nonatomic is considerably faster than atomic.
What atomic does not do is make any guarantees about thread safety. If thread A is calling the getter simultaneously with thread B and C calling the setter with different values, thread A may get any one of the three values returned -- the one prior to any setters being called or either of the values passed into the setters in B and C. Likewise, the object may end up with the value from B or C, no way to tell.
Ensuring data integrity -- one of the primary challenges of multi-threaded programming -- is achieved by other means.
Assign, retain, copy
In a nutshell, assign vs retain vs copy determines how the synthesized accessors interact with the Objective-C memory management scheme:
assign is the default and simply performs a variable assignment
retain specifies the new value should be sent -retain on assignment and the old value sent release
copy specifies the new value should be sent -copy on assignment and the old value sent release.
Remember that retain is done on the created object (it increases the reference count) whereas copy creates a new object. The difference, then, is whether you want to add another retain to the object or create an entirely new object.
Properties are a good technique to expose values. You shouldn't expose all instance variables as that would break good OOP encapsulation.
Here is Apple's documentation on the matter.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html
A key point is:
Declared properties address the problems with standard accessor
methods by providing the following features:
The property declaration provides a clear, explicit specification of
how the accessor methods behave.
The compiler can synthesize accessor methods for you, according to
the specification you provide in the declaration. This means you have
less code to write and maintain.
Properties are represented syntactically as identifiers and are
scoped, so the compiler can detect use of undeclared properties.
Properties enable automatic handling of the variables. So when you do a synthesize the compiler will generate your getters and setters allowing one to do class.variableName = value (indicating that the compiler will execute [class variableName:value].
Pretty decent explanation of the properties here: http://cocoacast.com/?q=node/103
If you need getters and setters to expose some instance variables, or you want some automatic retain/release memory management or thread safe accessors, then properties are a less verbose way to automatically create these smart getters and setters. If you don't want to expose something outside an object or thread, and don't want runtime memory management (say, for some malloc'd C struct) then properties might either a waste, or syntactic sugar (which may or may not improve code readability), or put there by a coder who doesn't know the difference.
The properties is a nice feature which gives you getter and setter method automatically by synthesize and give you relief by not setting and getting the value.
A property may be declared as "readonly", and may be provided with storage semantics such as "assign", "copy" or "retain". By default, properties are considered atomic, which results in a lock preventing multiple threads from accessing them at the same time. A property can be declared as "nonatomic", which removes this lock (reference from http://en.wikipedia.org/wiki/Objective-C#Properties).

ObjectiveC ivars or #property

Working on iPhone, after a lot of headache and memory problems I just realized from other examples that we do not need to necessarly create #properties for each instance variable we define in header file. And actually I found out ivars easy to just allocate and release it after I use anywhere in the class, for #properties I have to use autorealese or I have serious problems and becareful how I allocate..
For instance for objects below, #properties(retain/copy..) is not used in headers in many examples;
{
NSURLConnection *connection;
NSMutableData *xmlData;
NsMutableString *string
}
But for some strings or object types #properties is used, I know that when we set #property cocoa creates some setters getters which are handling the relasing and retaining of the objects. But seems like as for xmlData or connection instance variables we do not need that and they do their job like this.
Are there some reference guidelines I can keep in mind on deciding whether or not to create #property's or just use simple ivars?
My only problem when using properties is not becuase I am lazy to define it, but when I carefully allocate and init them in code, I have to use autorelase and dont feel like I have the control when to release reset and allocate it again, and it gives me one more thing to worry about while and when and how should I release, reset it. I find ivars I can alloc and release anytime once anywhere easily without worrying about anything..or I am missing other things here.
Tnx
There seem to still be some misconceptions flying around about properties.
that we do not need to necessarly create #properties for each instance variable we define in header file
Correct. You can use private instance variables directly in your implementation file. However, since synthesized properties come with free memory management, you might as well take advantage. My rule of thumb is to use the ivar directly until the first time I find myself writing:
[ivar release];
ivar = [newIvar retain];
As Sam says, there is already a potential bug there if iVar == newIVar. This is the point at which I switch from using ivars directly to creating a property. However, I put the declaration of the new property in a class extension in the implementation file. This means that the property is officially not part of the public interface (and will cause compiler warnings if used accidentally).
when we set #property cocoa creates some setters getters which are handling the relasing and retaining of the objects.
Actually, no. The #property just declares a property. In order to automatically generate the getter and setter, you need to #synthesize it. You could, alternatively write your own getters and setter which do not even have to reference a real ivar.
Technically, you should not use the property in the init or dealloc methods because a subclass might have overridden them or (in dealloc) you might set off a KVO notification.
From Sam's answer and comments
If you want a property regardless, you could use a private interface at the top of the implementation file
As I say above, private categories have sort of been obsoleted by class extensions (which is near enough the same thing but allows you to put the implementation of the methods in the main class implementation).
If you want the benefits of using dot notation shorthand
Some of us would argue that there are no benefits to dot notation. It's a gratuitous and needless pollution of the struct member syntax. However, dot notation has no relation to #property declarations. You can use dot notation for any accessors no matter how they were declared, provided they adhere to the pattern -foo and and -setFoo:
Create properties only for variables that need to be accessed from outside the class. Any class variables that are used internally need not have getters/setters defined.
Generally speaking an abundance of properties indicates high coupling and poor encapsulation. You should restrict what variables your class exposes in the interface.
EDITED to respond to comment:
Using properties over direct access may be preferred because it gives you easy memory management.. for example:
// interface
#property (retain) Object *someVar;
// implementation
self.someVar = otherVar;
is the same as
// implementation
if (_someVar != othervar)
{
[_someVar release]
_someVar = [otherVar retain];
}
However you should not needlessly expose vars in your interface because it opens the class up for people to use in the wrong way.
If you want a property regardless, you could use a private interface at the top of the implementation file
#interface TheClass(Private)
// private stuff
#end
First of all, let me say that Sam's answer is complete, IMO, and gives you clear guidelines (+1 from me).
My only problem when using properties is not becuase I am lazy to define it, but when I carefully allocate and init them in code, I have to use autorelase and dont feel like I have the control when to release reset and allocate it again, and it gives me one more thing to worry about while and when and how should I release, reset it. I find ivars I can alloc and release anytime once anywhere easily without worrying about anything..or I am missing other things here.
You should not worry about autorelease in the following idiom:
self.stringProperty = [[[NSString alloc] initWith...] autorelease];
because this is the way that things are meant to work;
EDIT: [the above statement has several parts:
the object is allocated and initialized (retain count is 1);
immediately, the allocated object is also autoreleased; this means that the object will be released automatically, (more or less) when the control flow gets back to the main loop;
in the very same statement, the allocated object is assigned to a retained property, self.stringProperty; this has the effect of (once again) incrementing the retain count;
So, it is true that autorelease adds some "ambiguity", because the object will be released at a time that you don't know precisely (but pretty soon anyway), but assigning to the retain property will increase the retain count so that you have full control over the lifetime of the object.]
If you don't like the autorelease you can always use a constructor method which gives you back an autoreleased object, when available:
self.stringProperty = [NSString stringWith...];
or assign directly to the ivar:
stringProperty = [[[NSString alloc] initWith...] autorelease];
because by accessing directly the ivar you are bypassing the setter and getter. Anyway, do the it only in this case (IMHO) to avoid ambiguities.
More in general, the autorelease glitch is the only drawback that using properties has over directly accessing the ivars. The rest are, IMO, only advantages that in many cases will save your life, and if not your life, a leak or a crash.
There is nothing you cannot do with directly accessing the ivars and taking care of when it is necessary to release before assigning, or not forgetting to set to nil after releasing, etc., but properties will do that easier for you, so my suggestion is simply use them and accept the autorelease shortcoming. It's only a matter of getting the basic "idioms" right.
It has long been custom to access ivars directly. That is, IMO, fine from inside the same class, although many properties are classes and then properties provide protection against retain/release issues.
IMO, it is, however, preferrable to encapsulate most ivars into properties, especially those that have retain/release semantics, but also those that need special handling, i.e. for which you write your own handlers, instead of using the synthesized ones. That way you can filter access to certain ivars, or even create properties that don't have any backing storage, and are just "aliases" to other properties, e.g. an Angle class that has a degrees property giving the angle in degrees, and a radians property denoting the same angle in radians (this is a simple conversion), or a property that must do a dictionary search to find its value, etc.
In Delphi, which was (AFAICT) one of the first languages with properties as language construct at all, it is customary to wrap ALL ivars in properties (but not all have to be public), and there are many such "unreal" (I am deliberately avoiding the term "virtual" here) properties, i.e. the ones that are only implemented in code, and not just getters and setters for an ivar.
Properties provide encapsulation, abstraction and a degree of protection against certain often made errors, and that is why they are to be preferred over direct access to ivars, IMO.
Addition
It doesn't make sense to declare and implement (either via #synthesize or with custom setters and getters) public properties for each ivar. Only expose publicly what others may need. Internal state can also be exposed to your own code via properties, but that should be done with a private or empty category in the implementation file. That way you get the automatic handling of retain/release and still don't expose them to the public.

Does it make a difference in performance if I use self.fooBar instead of fooBar?

Note: I know exactly what a property is. This question is about performance.
Using self.fooBar for READ access seems a waste of time for me. Unnecessary Objective-C messaging is going on. The getters typically simply pass along the ivar, so as long as it's pretty sure there will be no reasonable getter method written, I think it's perfectly fine to bypass this heavy guy.
Objective-C messaging is about 20 times slower than direct calls. So if there is some high-performance-high-frequency code with hundreds of properties in use, maybe it does help a lot to avoid unnessessary objective-c messaging?
Or am I wasting my time thinking about this?
This kind of premature optimization should really be postponed until you actually notice or measure (with Instruments.app) a real problem.
No offence, but you're probably wasting your time thinking about it. Unless you have code that accesses that property thousands of times a second, then you're not going to see any performance differences.
The two aren't really interchangeable (ok some of the times they are). Access the ivar directly when that is what you need and use the accessor methods when that is what you need. It will probably depend on the the class hierarchy, the implementation of the class, is the code thread safe etc, etc.
All things that are largely upto you if it's your code. Might someone want to subclass this class and write a custom implementation of -foobar that always returned #"BOO" but they find that the superClass method -printFooBar now prints #"hello darling" because it prints out the value of the variable foobar instead of the value returned from self.foobar ?
Calling the accessor method does have more overhead than using the variable directly, but there are more things to consider than performance. Personally i find the position "always use the accessor method" just as ridiculous as saying "never use the accessor methods" - which would clearly be ridiculous.
Yes using property getters are much slower than direct access. A property getter is useful outside of the self class (and categories) for encapsulation, but I see no benefits using a self.ivar getter, unless you have overridden the getter to something else.
(And why are you using self.ivar in the first place?)
The only cases where self.ivar will be different from self->ivar are:
The property is atomic, so self.ivar will be similar to
spin_lock(&ivar_lock);
id retval = [ivar retain];
spin_unlock(&ivar_lock);
return [retval autorelease];
for an id property, and
spin_lock(&ivar_lock);
spin_lock(&destination_lock);
memcpy(&destination, &ivar, sizeof(ivar));
spin_unlock(&ivar_lock);
spin_unlock(&destination_lock);
for a struct. There is no difference between the two when the property is nonatomic.
When the class is not final. A category of the class or a subclass can override the property getter to something else. But I think overriding a concrete property is not a good style.
Like what the others have said, unless you have tested that the getter is a hot spot, changing it back to direct ivar access won't help much.
Some may disagree, but I happen to like accessing the ivar directly and bypassing the whole messaging business where possible. I think it makes my intentions clearer, since if I ever need to message the getter (for memory management or the like), then I will.
It's a tiny bit less efficient, but you still should generally not make your object state public. Although public members are considered bad in most OO languages, there's actually a pragmatic reason why in Objective-C: The framework uses your "getter" and "setter" methods to make certain things automatic, such as memory management and KVO notifications. With ivars accessed from multiple places, every piece of client code needs to fully understand all the responsibilities that the accessor methods were taking on and perform those duties in the exact same way itself.
So it's no "absolutely don't access your own ivars," but just make sure you fully understand what it entails in a given situation.

What are best practices that you use when writing Objective-C and Cocoa? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I know about the HIG (which is quite handy!), but what programming practices do you use when writing Objective-C, and more specifically when using Cocoa (or CocoaTouch).
There are a few things I have started to do that I do not think are standard:
1) With the advent of properties, I no longer use "_" to prefix "private" class variables. After all, if a variable can be accessed by other classes shouldn't there be a property for it? I always disliked the "_" prefix for making code uglier, and now I can leave it out.
2) Speaking of private things, I prefer to place private method definitions within the .m file in a class extension like so:
#import "MyClass.h"
#interface MyClass ()
- (void) someMethod;
- (void) someOtherMethod;
#end
#implementation MyClass
Why clutter up the .h file with things outsiders should not care about? The empty () works for private categories in the .m file, and issues compile warnings if you do not implement the methods declared.
3) I have taken to putting dealloc at the top of the .m file, just below the #synthesize directives. Shouldn't what you dealloc be at the top of the list of things you want to think about in a class? That is especially true in an environment like the iPhone.
3.5) In table cells, make every element (including the cell itself) opaque for performance. That means setting the appropriate background color in everything.
3.6) When using an NSURLConnection, as a rule you may well want to implement the delegate method:
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
return nil;
}
I find most web calls are very singular and it's more the exception than the rule you'll be wanting responses cached, especially for web service calls. Implementing the method as shown disables caching of responses.
Also of interest, are some good iPhone specific tips from Joseph Mattiello (received in an iPhone mailing list). There are more, but these were the most generally useful I thought (note that a few bits have now been slightly edited from the original to include details offered in responses):
4) Only use double precision if you have to, such as when working with CoreLocation. Make sure you end your constants in 'f' to make gcc store them as floats.
float val = someFloat * 2.2f;
This is mostly important when someFloat may actually be a double, you don't need the mixed-mode math, since you're losing precision in 'val' on storage. While floating-point numbers are supported in hardware on iPhones, it may still take more time to do double-precision arithmetic as opposed to single precision. References:
Double vs float on the iPhone
iPhone/iPad double precision math
On the older phones supposedly calculations operate at the same speed but you can have more single precision components in registers than doubles, so for many calculations single precision will end up being faster.
5) Set your properties as nonatomic. They're atomic by default and upon synthesis, semaphore code will be created to prevent multi-threading problems. 99% of you probably don't need to worry about this and the code is much less bloated and more memory-efficient when set to nonatomic.
6) SQLite can be a very, very fast way to cache large data sets. A map application for instance can cache its tiles into SQLite files. The most expensive part is disk I/O. Avoid many small writes by sending BEGIN; and COMMIT; between large blocks. We use a 2 second timer for instance that resets on each new submit. When it expires, we send COMMIT; , which causes all your writes to go in one large chunk. SQLite stores transaction data to disk and doing this Begin/End wrapping avoids creation of many transaction files, grouping all of the transactions into one file.
Also, SQL will block your GUI if it's on your main thread. If you have a very long query, It's a good idea to store your queries as static objects, and run your SQL on a separate thread. Make sure to wrap anything that modifies the database for query strings in #synchronize() {} blocks. For short queries just leave things on the main thread for easier convenience.
More SQLite optimization tips are here, though the document appears out of date many of the points are probably still good;
http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html
Don't use unknown strings as format strings
When methods or functions take a format string argument, you should make sure that you have control over the content of the format string.
For example, when logging strings, it is tempting to pass the string variable as the sole argument to NSLog:
NSString *aString = // get a string from somewhere;
NSLog(aString);
The problem with this is that the string may contain characters that are interpreted as format strings. This can lead to erroneous output, crashes, and security problems. Instead, you should substitute the string variable into a format string:
NSLog(#"%#", aString);
Use standard Cocoa naming and formatting conventions and terminology rather than whatever you're used to from another environment. There are lots of Cocoa developers out there, and when another one of them starts working with your code, it'll be much more approachable if it looks and feels similar to other Cocoa code.
Examples of what to do and what not to do:
Don't declare id m_something; in an object's interface and call it a member variable or field; use something or _something for its name and call it an instance variable.
Don't name a getter -getSomething; the proper Cocoa name is just -something.
Don't name a setter -something:; it should be -setSomething:
The method name is interspersed with the arguments and includes colons; it's -[NSObject performSelector:withObject:], not NSObject::performSelector.
Use inter-caps (CamelCase) in method names, parameters, variables, class names, etc. rather than underbars (underscores).
Class names start with an upper-case letter, variable and method names with lower-case.
Whatever else you do, don't use Win16/Win32-style Hungarian notation. Even Microsoft gave up on that with the move to the .NET platform.
IBOutlets
Historically, memory management of outlets has been poor.
Current best practice is to declare outlets as properties:
#interface MyClass :NSObject {
NSTextField *textField;
}
#property (nonatomic, retain) IBOutlet NSTextField *textField;
#end
Using properties makes the memory management semantics clear; it also provides a consistent pattern if you use instance variable synthesis.
Use the LLVM/Clang Static Analyzer
NOTE: Under Xcode 4 this is now built into the IDE.
You use the Clang Static Analyzer to -- unsurprisingly -- analyse your C and Objective-C code (no C++ yet) on Mac OS X 10.5. It's trivial to install and use:
Download the latest version from this page.
From the command-line, cd to your project directory.
Execute scan-build -k -V xcodebuild.
(There are some additional constraints etc., in particular you should analyze a project in its "Debug" configuration -- see http://clang.llvm.org/StaticAnalysisUsage.html for details -- the but that's more-or-less what it boils down to.)
The analyser then produces a set of web pages for you that shows likely memory management and other basic problems that the compiler is unable to detect.
This is subtle one but handy one. If you're passing yourself as a delegate to another object, reset that object's delegate before you dealloc.
- (void)dealloc
{
self.someObject.delegate = NULL;
self.someObject = NULL;
//
[super dealloc];
}
By doing this you're ensuring that no more delegate methods will get sent. As you're about to dealloc and disappear into the ether you want to make sure that nothing can send you any more messages by accident. Remember self.someObject could be retained by another object (it could be a singleton or on the autorelease pool or whatever) and until you tell it "stop sending me messages!", it thinks your just-about-to-be-dealloced object is fair game.
Getting into this habit will save you from lots of weird crashes that are a pain to debug.
The same principal applies to Key Value Observation, and NSNotifications too.
Edit:
Even more defensive, change:
self.someObject.delegate = NULL;
into:
if (self.someObject.delegate == self)
self.someObject.delegate = NULL;
#kendell
Instead of:
#interface MyClass (private)
- (void) someMethod
- (void) someOtherMethod
#end
Use:
#interface MyClass ()
- (void) someMethod
- (void) someOtherMethod
#end
New in Objective-C 2.0.
Class extensions are described in Apple's Objective-C 2.0 Reference.
"Class extensions allow you to declare additional required API for a class in locations other than within the primary class #interface block"
So they're part of the actual class - and NOT a (private) category in addition to the class. Subtle but important difference.
Avoid autorelease
Since you typically(1) don't have direct control over their lifetime, autoreleased objects can persist for a comparatively long time and unnecessarily increase the memory footprint of your application. Whilst on the desktop this may be of little consequence, on more constrained platforms this can be a significant issue. On all platforms, therefore, and especially on more constrained platforms, it is considered best practice to avoid using methods that would lead to autoreleased objects and instead you are encouraged to use the alloc/init pattern.
Thus, rather than:
aVariable = [AClass convenienceMethod];
where able, you should instead use:
aVariable = [[AClass alloc] init];
// do things with aVariable
[aVariable release];
When you're writing your own methods that return a newly-created object, you can take advantage of Cocoa's naming convention to flag to the receiver that it must be released by prepending the method name with "new".
Thus, instead of:
- (MyClass *)convenienceMethod {
MyClass *instance = [[[self alloc] init] autorelease];
// configure instance
return instance;
}
you could write:
- (MyClass *)newInstance {
MyClass *instance = [[self alloc] init];
// configure instance
return instance;
}
Since the method name begins with "new", consumers of your API know that they're responsible for releasing the received object (see, for example, NSObjectController's newObject method).
(1) You can take control by using your own local autorelease pools. For more on this, see Autorelease Pools.
Some of these have already been mentioned, but here's what I can think of off the top of my head:
Follow KVO naming rules. Even if you don't use KVO now, in my experience often times it's still beneficial in the future. And if you are using KVO or bindings, you need to know things are going work the way they are supposed to. This covers not just accessor methods and instance variables, but to-many relationships, validation, auto-notifying dependent keys, and so on.
Put private methods in a category. Not just the interface, but the implementation as well. It's good to have some distance conceptually between private and non-private methods. I include everything in my .m file.
Put background thread methods in a category. Same as above. I've found it's good to keep a clear conceptual barrier when you're thinking about what's on the main thread and what's not.
Use #pragma mark [section]. Usually I group by my own methods, each subclass's overrides, and any information or formal protocols. This makes it a lot easier to jump to exactly what I'm looking for. On the same topic, group similar methods (like a table view's delegate methods) together, don't just stick them anywhere.
Prefix private methods & ivars with _. I like the way it looks, and I'm less likely to use an ivar when I mean a property by accident.
Don't use mutator methods / properties in init & dealloc. I've never had anything bad happen because of it, but I can see the logic if you change the method to do something that depends on the state of your object.
Put IBOutlets in properties. I actually just read this one here, but I'm going to start doing it. Regardless of any memory benefits, it seems better stylistically (at least to me).
Avoid writing code you don't absolutely need. This really covers a lot of things, like making ivars when a #define will do, or caching an array instead of sorting it each time the data is needed. There's a lot I could say about this, but the bottom line is don't write code until you need it, or the profiler tells you to. It makes things a lot easier to maintain in the long run.
Finish what you start. Having a lot of half-finished, buggy code is the fastest way to kill a project dead. If you need a stub method that's fine, just indicate it by putting NSLog( #"stub" ) inside, or however you want to keep track of things.
Write unit tests. You can test a lot of things in Cocoa that might be harder in other frameworks. For example, with UI code, you can generally verify that things are connected as they should be and trust that they'll work when used. And you can set up state & invoke delegate methods easily to test them.
You also don't have public vs. protected vs. private method visibility getting in the way of writing tests for your internals.
Golden Rule: If you alloc then you release!
UPDATE: Unless you are using ARC
Don't write Objective-C as if it were Java/C#/C++/etc.
I once saw a team used to writing Java EE web applications try to write a Cocoa desktop application. As if it was a Java EE web application. There was a lot of AbstractFooFactory and FooFactory and IFoo and Foo flying around when all they really needed was a Foo class and possibly a Fooable protocol.
Part of ensuring you don't do this is truly understanding the differences in the language. For example, you don't need the abstract factory and factory classes above because Objective-C class methods are dispatched just as dynamically as instance methods, and can be overridden in subclasses.
Make sure you bookmark the Debugging Magic page. This should be your first stop when banging your head against a wall while trying to find the source of a Cocoa bug.
For example, it will tell you how to find the method where you first allocated memory that later is causing crashes (like during app termination).
Try to avoid what I have now decided to call Newbiecategoryaholism. When newcomers to Objective-C discover categories they often go hog wild, adding useful little categories to every class in existence ("What? i can add a method to convert a number to roman numerals to NSNumber rock on!").
Don't do this.
Your code will be more portable and easier to understand with out dozens of little category methods sprinkled on top of two dozen foundation classes.
Most of the time when you really think you need a category method to help streamline some code you'll find you never end up reusing the method.
There are other dangers too, unless you're namespacing your category methods (and who besides the utterly insane ddribin is?) there is a chance that Apple, or a plugin, or something else running in your address space will also define the same category method with the same name with a slightly different side effect....
OK. Now that you've been warned, ignore the "don't do this part". But exercise extreme restraint.
Resist subclassing the world. In Cocoa a lot is done through delegation and use of the underlying runtime that in other frameworks is done through subclassing.
For example, in Java you use instances of anonymous *Listener subclasses a lot and in .NET you use your EventArgs subclasses a lot. In Cocoa, you don't do either — the target-action is used instead.
Sort strings as the user wants
When you sort strings to present to the user, you should not use the simple compare: method. Instead, you should always use localized comparison methods such as localizedCompare: or localizedCaseInsensitiveCompare:.
For more details, see Searching, Comparing, and Sorting Strings.
Declared Properties
You should typically use the Objective-C 2.0 Declared Properties feature for all your properties. If they are not public, add them in a class extension. Using declared properties makes the memory management semantics immediately clear, and makes it easier for you to check your dealloc method -- if you group your property declarations together you can quickly scan them and compare with the implementation of your dealloc method.
You should think hard before not marking properties as 'nonatomic'. As The Objective C Programming Language Guide notes, properties are atomic by default, and incur considerable overhead. Moreover, simply making all your properties atomic does not make your application thread-safe. Also note, of course, that if you don't specify 'nonatomic' and implement your own accessor methods (rather than synthesising them), you must implement them in an atomic fashion.
Think about nil values
As this question notes, messages to nil are valid in Objective-C. Whilst this is frequently an advantage -- leading to cleaner and more natural code -- the feature can occasionally lead to peculiar and difficult-to-track-down bugs if you get a nil value when you weren't expecting it.
Use NSAssert and friends.
I use nil as valid object all the time ... especially sending messages to nil is perfectly valid in Obj-C.
However if I really want to make sure about the state of a variable, I use NSAssert and NSParameterAssert, which helps to track down problems easily.
Simple but oft-forgotten one. According to spec:
In general, methods in different
classes that have the same selector
(the same name) must also share the
same return and argument types. This
constraint is imposed by the compiler
to allow dynamic binding.
in which case all the same named selectors, even if in different classes, will be regarded as to have identical return/argument types. Here is a simple example.
#interface FooInt:NSObject{}
-(int) print;
#end
#implementation FooInt
-(int) print{
return 5;
}
#end
#interface FooFloat:NSObject{}
-(float) print;
#end
#implementation FooFloat
-(float) print{
return 3.3;
}
#end
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
id f1=[[FooFloat alloc]init];
//prints 0, runtime considers [f1 print] to return int, as f1's type is "id" and FooInt precedes FooBar
NSLog(#"%f",[f1 print]);
FooFloat* f2=[[FooFloat alloc]init];
//prints 3.3 expectedly as the static type is FooFloat
NSLog(#"%f",[f2 print]);
[f1 release];
[f2 release]
[pool drain];
return 0;
}
If you're using Leopard (Mac OS X 10.5) or later, you can use the Instruments application to find and track memory leaks. After building your program in Xcode, select Run > Start with Performance Tool > Leaks.
Even if your app doesn't show any leaks, you may be keeping objects around too long. In Instruments, you can use the ObjectAlloc instrument for this. Select the ObjectAlloc instrument in your Instruments document, and bring up the instrument's detail (if it isn't already showing) by choosing View > Detail (it should have a check mark next to it). Under "Allocation Lifespan" in the ObjectAlloc detail, make sure you choose the radio button next to "Created & Still Living".
Now whenever you stop recording your application, selecting the ObjectAlloc tool will show you how many references there are to each still-living object in your application in the "# Net" column. Make sure you not only look at your own classes, but also the classes of your NIB files' top-level objects. For example, if you have no windows on the screen, and you see references to a still-living NSWindow, you may have not released it in your code.
Clean up in dealloc.
This is one of the easiest things to forget - esp. when coding at 150mph. Always, always, always clean up your attributes/member variables in dealloc.
I like to use Objc 2 attributes - with the new dot notation - so this makes the cleanup painless. Often as simple as:
- (void)dealloc
{
self.someAttribute = NULL;
[super dealloc];
}
This will take care of the release for you and set the attribute to NULL (which I consider defensive programming - in case another method further down in dealloc accesses the member variable again - rare but could happen).
With GC turned on in 10.5, this isn't needed so much any more - but you might still need to clean up others resources you create, you can do that in the finalize method instead.
All these comments are great, but I'm really surprised nobody mentioned Google's Objective-C Style Guide that was published a while back. I think they have done a very thorough job.
Also, semi-related topic (with room for more responses!):
What are those little Xcode tips & tricks you wish you knew about 2 years ago?.
Don't forget that NSWindowController and NSViewController will release the top-level objects of the NIB files they govern.
If you manually load a NIB file, you are responsible for releasing that NIB's top-level objects when you are done with them.
One rather obvious one for a beginner to use: utilize Xcode's auto-indentation feature for your code. Even if you are copy/pasting from another source, once you have pasted the code, you can select the entire block of code, right click on it, and then choose the option to re-indent everything within that block.
Xcode will actually parse through that section and indent it based on brackets, loops, etc. It's a lot more efficient than hitting the space bar or tab key for each and every line.
I know I overlooked this when first getting into Cocoa programming.
Make sure you understand memory management responsibilities regarding NIB files. You are responsible for releasing the top-level objects in any NIB file you load. Read Apple's Documentation on the subject.
Turn on all GCC warnings, then turn off those that are regularly caused by Apple's headers to reduce noise.
Also run Clang static analysis frequently; you can enable it for all builds via the "Run Static Analyzer" build setting.
Write unit tests and run them with each build.
Variables and properties
1/ Keeping your headers clean, hiding implementation
Don't include instance variables in your header. Private variables put into class continuation as properties. Public variables declare as public properties in your header.
If it should be only read, declare it as readonly and overwrite it as readwrite in class continutation.
Basically I am not using variables at all, only properties.
2/ Give your properties a non-default variable name, example:
#synthesize property = property_;
Reason 1: You will catch errors caused by forgetting "self." when assigning the property.
Reason 2: From my experiments, Leak Analyzer in Instruments has problems to detect leaking property with default name.
3/ Never use retain or release directly on properties (or only in very exceptional situations). In your dealloc just assign them a nil. Retain properties are meant to handle retain/release by themselves. You never know if a setter is not, for example, adding or removing observers. You should use the variable directly only inside its setter and getter.
Views
1/ Put every view definition into a xib, if you can (the exception is usually dynamic content and layer settings). It saves time (it's easier than writing code), it's easy to change and it keeps your code clean.
2/ Don't try to optimize views by decreasing the number of views. Don't create UIImageView in your code instead of xib just because you want to add subviews into it. Use UIImageView as background instead. The view framework can handle hundreds of views without problems.
3/ IBOutlets don't have to be always retained (or strong). Note that most of your IBOutlets are part of your view hierarchy and thus implicitly retained.
4/ Release all IBOutlets in viewDidUnload
5/ Call viewDidUnload from your dealloc method. It is not implicitly called.
Memory
1/ Autorelease objects when you create them. Many bugs are caused by moving your release call into one if-else branch or after a return statement. Release instead of autorelease should be used only in exceptional situations - e.g. when you are waiting for a runloop and you don't want your object to be autoreleased too early.
2/ Even if you are using Authomatic Reference Counting, you have to understand perfectly how retain-release methods work. Using retain-release manually is not more complicated than ARC, in both cases you have to thing about leaks and retain-cycles.
Consider using retain-release manually on big projects or complicated object hierarchies.
Comments
1/ Make your code autodocumented.
Every variable name and method name should tell what it is doing. If code is written correctly (you need a lot of practice in this), you won't need any code comments (not the same as documentation comments). Algorithms can be complicated but the code should be always simple.
2/ Sometimes, you'll need a comment. Usually to describe a non apparent code behavior or hack. If you feel you have to write a comment, first try to rewrite the code to be simpler and without the need of comments.
Indentation
1/ Don't increase indentation too much.
Most of your method code should be indented on the method level. Nested blocks (if, for etc.) decrease readability. If you have three nested blocks, you should try to put the inner blocks into a separate method. Four or more nested blocks should be never used.
If most of your method code is inside of an if, negate the if condition, example:
if (self) {
//... long initialization code ...
}
return self;
if (!self) {
return nil;
}
//... long initialization code ...
return self;
Understand C code, mainly C structs
Note that Obj-C is only a light OOP layer over C language. You should understand how basic code structures in C work (enums, structs, arrays, pointers etc).
Example:
view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height + 20);
is the same as:
CGRect frame = view.frame;
frame.size.height += 20;
view.frame = frame;
And many more
Mantain your own coding standards document and update it often. Try to learn from your bugs. Understand why a bug was created and try to avoid it using coding standards.
Our coding standards have currently about 20 pages, a mix of Java Coding Standards, Google Obj-C/C++ Standards and our own addings. Document your code, use standard standard indentation, white spaces and blank lines on the right places etc.
Be more functional.
Objective-C is object-oriented language, but Cocoa framework functional-style aware, and is designed functional style in many cases.
There is separation of mutability. Use immutable classes as primary, and mutable object as secondary. For instance, use NSArray primarily, and use NSMutableArray only when you need.
There is pure functions. Not so many, buy many of framework APIs are designed like pure function. Look at functions such as CGRectMake() or CGAffineTransformMake(). Obviously pointer form looks more efficient. However indirect argument with pointers can't offer side-effect-free. Design structures purely as much as possible.
Separate even state objects. Use -copy instead of -retain when passing a value to other object. Because shared state can influence mutation to value in other object silently. So can't be side-effect-free. If you have a value from external from object, copy it. So it's also important designing shared state as minimal as possible.
However don't be afraid of using impure functions too.
There is lazy evaluation. See something like -[UIViewController view] property. The view won't be created when the object is created. It'll be created when caller reading view property at first time. UIImage will not be loaded until it actually being drawn. There are many implementation like this design. This kind of designs are very helpful for resource management, but if you don't know the concept of lazy evaluation, it's not easy to understand behavior of them.
There is closure. Use C-blocks as much as possible. This will simplify your life greatly. But read once more about block-memory-management before using it.
There is semi-auto GC. NSAutoreleasePool. Use -autorelease primary. Use manual -retain/-release secondary when you really need. (ex: memory optimization, explicit resource deletion)