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).
-
see this blog post, very nice. http://ironwolf.dangerousgames.com/blog/archives/913 – user392412 Apr 02 '12 at 15:57
33 Answers
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:
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

- 1
- 1

- 74,769
- 26
- 128
- 150
-
3
-
8Class extensions are now the preferred way for private methods: http://developer.apple.com/Mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCategories.html#//apple_ref/doc/uid/TP30001163-CH20-SW2 – Casebash Feb 03 '10 at 02:06
-
9Your advice about doubles on the iPhone is out of date http://stackoverflow.com/questions/1622729/double-vs-float-on-the-iphone – Casebash Feb 03 '10 at 02:07
-
Wow, I'm just getting started on iPhone dev and this is incredible! – Tejaswi Yerukalapudi Mar 31 '10 at 04:01
-
Casebash - thanks for the link, although the info was out of date with the 3Gs it appears you have even more reason to use single precision FP than ever before! I updated that section of the answer. – Kendall Helmstetter Gelner Mar 31 '10 at 19:44
-
3Not out of date; entirely wrong: the original iPhone supported floats and doubles in hardware at approximately the same speed. SQLite also doesn't keep transactions in memory; they're journaled on disk. Only long queries block your UI; it's less messy to run everything in the main thread and use faster queries. – tc. Sep 23 '10 at 01:26
-
1@tc: I corrected the SQL item about transactions, note that I myself did not write those last four or so items. I also clarified the part about moving queries to the background was for very long queries only (sometimes you just can't get them shorter). But to call the whole thing "wrong" because of a few points is I feel rather extreme. Also, the answer above already stated: "On the older phones supposedly calculations operate at the same speed" but note the part about the greater number of single precision registers making them still preferable. – Kendall Helmstetter Gelner Sep 23 '10 at 07:50
-
The bit about nonatomic properties is premature optimisation. It's better to leave them as default and change them to nonatomic if profiling demonstrates a significant performance improvement can be obtained. – JeremyP Sep 23 '10 at 10:34
-
That optimization is not premature at all. There is no benefit to leaving them atomic and in fact presents a potential danger with deadlock if you don't know what you are doing and actually use them multi-threaded. It's a common technique recommended by many experienced ObjC developers and the default on applications like Accessorizer that generate property settings. – Kendall Helmstetter Gelner Sep 23 '10 at 16:10
-
+1 for point #5. i wish nonatomic were the default. atomic is pretty useless (imo) - the dev (or client) should know when multithreading is an issue or not, and they should address those issues appropriately. 'it usually works, although it's very time consuming' is not a 'feature'. – justin Feb 01 '11 at 06:09
-
Regarding second point .... Private method declaration:: There is no need to write any category. I can still write methods without declaration and without any warning. Here is the way: - (void) myPrivateMethod {} - (void)myClassMethod { [self myPrivateMethod]; } Check this out... – Mrunal Jan 11 '12 at 18:14
-
1The information about doubles here is flat out wrong I'm afraid. Even the linked question referenced as a source for (4) contradicts the statement completely. Once more: iDevices of all flavours support double precision math in hardware. – Tim Jan 13 '12 at 20:25
-
@Tim Just because double precision math is supported in hardware does not make it faster than single precision math. Can you provide a link or example to show there is truly no difference or that it would be faster? Note my text in fact explicitly states double precision math is supported in hardware... and the links provided do not contradict, they show how single precision can be faster. – Kendall Helmstetter Gelner Jan 14 '12 at 04:57
-
@mrunal - that technique works only when your method is being called by methods that follow it. Often times for organizational reasons you may want to put a helper method after some other methods that call it - that's when the private category comes in. I don't always put method definitions in a private category myself, but it's important to know it's an option rather than structuring your methods unnaturally. – Kendall Helmstetter Gelner Jan 14 '12 at 04:59
-
@KendallHelmstetterGelner your edit addresses my objection perfectly; thanks. My issue wasn't with whether double or single precision was faster, it was with your claim that double precision math was emulated in software and not supported in the hardware. I should have been clearer. – Tim Jan 14 '12 at 05:51
-
@KendallHelmstetterGelner - May i know which kind of organizational reasons? – Mrunal Jan 14 '12 at 08:13
-
Grouping all view controller methods together is one example, with helper methods located after at the end of a file so as to make them easier to find. – Kendall Helmstetter Gelner Jan 14 '12 at 09:01
-
@KendallHelmstetterGelner Current versions of clang do not depend on method declarations for the current compilation unit any more. So they can now be left out from the class extension without harm. – Nikolai Ruhe May 02 '12 at 23:52
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);

- 6,846
- 6
- 43
- 54

- 8,201
- 3
- 39
- 39
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; usesomething
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:]
, notNSObject::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.

- 23,010
- 22
- 73
- 116

- 54,380
- 8
- 73
- 102
-
5I would argue, don't use setSomething:/something at all - instead use properties. At this point there are few people that really need to target Tiger (the only reason not to use properties) – Kendall Helmstetter Gelner Oct 01 '08 at 16:14
-
18Properties still generate accessor methods for you, and the getter=/setter= attributes on the property let you specify the names of the methods. In addition, you can use [foo something] syntax instead of foo.something syntax with properties. So accessor naming is still relevant. – Chris Hanson Oct 01 '08 at 22:44
-
3This is a great reference for someone comming from C++, where I did most of the things you advise against. – Clinton Blackmore Jul 31 '09 at 23:17
-
1Sometimes it is not possible to use the standard setters/getters. I had a case where the setter had to also save something to file/database etc... So the advice still stands for handcrafted setters/getters. – John Smith Dec 07 '09 at 19:53
-
4A setter should not be causing something to be saved to the database. There's a reason Core Data has a -save: method on NSManagedObjectContext, rather than have setters generate immediate updates. – Chris Hanson Dec 18 '09 at 09:28
-
1it was not an option in my case. The core data method could not possibly work. Sometimes textbook advice must be overridden. – John Smith Jan 09 '10 at 10:54
-
2I doubt it wasn't an option, it may have required revisiting your app architecture however. (To be clear: I'm not saying "You should have used Core Data." I'm saying "Setters shouldn't save to database.") Having a context to manage an object graph, rather than saving individual objects in it, is virtually always both possible and a better solution. – Chris Hanson Jan 12 '10 at 20:51
-
1I'll just chime in here and mention that anything Chris says about Core Data should be taken as authoritative. He was one of the engineers who wrote it. – NSResponder Apr 23 '10 at 08:56
-
Admittedly, I'm new to iOS, but there are places in Apple's documentation where they seem to use "member variable" and "instance variable" interchangeably (for example http://bit.ly/hR8RGI), so I don't see that as a hard and fast rule. – Brandon DuRette Mar 26 '11 at 06:53
-
Also, if you want to target older Mac OS X systems (pre 10.5) you have no option but to use accessor methods. – dreamlax Mar 28 '11 at 05:04
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.

- 8,201
- 3
- 39
- 39
-
1wouldn't loading of nib retain it twice then? (once in nib, second by assignment to property). Am I supposed to release those in dealloc? – Kornel Jun 17 '09 at 09:40
-
6You have to nil the outlets in viewDidUnload (iPhone OS 3.0+) or in a custom setView: method to avoid leaks. Obviously you should release in dealloc as well. – Frank Szczerba Jul 10 '09 at 18:15
-
2Keep in mind that not everyone agrees with this style: http://weblog.bignerdranch.com/?p=95 – Michael Aug 17 '09 at 07:48
-
This is the way Apple does things too. "Beginning iPhone 3 development" mentions this change from previous versions too. – ustun Oct 14 '09 at 18:04
-
I mentioned this in another comment, but should have placed it here: Once dynamic ivar synthesis starts happening for iOS apps (if/when?), you'll be glad you put IBOutlet on the property vs. the ivar! – Joe D'Andrea Aug 30 '10 at 15:48
-
@mmalc : do you have some kind of proof for that ? the votes seems to believe you, but I'm skeptic. – Marcel Falliere Dec 10 '10 at 09:27
-
@Michael: The post you linked to disagrees with making IBOutlets `retain`, not with sticking IBOutlet on the property instead of the ivar. – tc. Jun 22 '11 at 02:38
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.

- 8,762
- 3
- 39
- 50

- 8,201
- 3
- 39
- 39
-
1I had some trouble getting this to work until I followed these instructions: http://www.oiledmachine.com/posts/2009/01/06/using-the-llvm-clang-static-analyzer-for-iphone-apps.html – bbrown May 11 '09 at 23:36
-
15In XCode 3.2.1 on Snow Leopard, it is already built in. You can either run it manually, using *Run -> Build and Analyze*, or you can enable it for all builds via the "Run Static Analyzer" build setting. Note that this tool presently only supports C and Objective-C, but not C++ / Objective-C++. – oefe Oct 18 '09 at 18:03
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;

- 8,762
- 3
- 39
- 50

- 11,962
- 14
- 43
- 54
-
8There's nothing subtle about this, the documentation clearly says that you are required to do this. From `Memory Management Programming Guide for Cocoa`: `Additional cases of weak references in Cocoa include, but are not restricted to, table data sources, outline view items, notification observers, and miscellaneous targets and delegates. In most cases, the weak-referenced object is aware of the other object’s weak reference to it, as is the case for circular references, and is responsible for notifying the other object when it deallocates.` – johne Jul 21 '09 at 04:06
-
Its better to use nil instead of NULL, because the NULL will not free up the memory. – Naveen Shan Oct 10 '11 at 05:47
-
@NaveenShan `nil == NULL`. They are exactly the same except that `nil` is an `id` and `NULL` is a `void *`. Your statement isn't true. – Oct 25 '11 at 13:38
-
@WTP yep, nil == NULL, but using nil is clearly the preferred way, if you look through apples example code fragments, theyre using nil everywhere, and as you said, nil is an id, which makes it preferrable over the void*, in cases where you send ids, that is. – Ahti Nov 23 '11 at 13:15
-
1@Ahti exactly, and `Nil` (uppercase) is of type `Class*`. Even though they are all equal, using the wrong one can introduce nasty little bugs, especially in Objective-C++. – Nov 23 '11 at 13:54
@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.

- 8,762
- 3
- 39
- 50

- 11,962
- 14
- 43
- 54
-
You could do that but I like to label it explicitly as a "private" section (more documentation than functional) though of course that's already plenty obvious from it being located in the .m file... – Kendall Helmstetter Gelner Oct 01 '08 at 04:03
-
2Except there _is_ a difference between private categories and class extensions: "Class extensions allow you to declare additional required API for a class in locations other than within the primary class @interface block, as illustrated in the following example:" See link in edit. – schwa Oct 01 '08 at 04:46
-
I agree there is a difference where the compiler will warn you when you have not implemented CE methods - but I do not find that aspect very important when all the methods are in the same file, and all private. I still prefer the maintainability aspect of marking the forward reference block private – Kendall Helmstetter Gelner Oct 01 '08 at 05:03
-
I can see arguing it's more maintainable to have the compiler keep the CE block in alignment with your code, but that seems to me to happen naturally through compiler warnings as methods change and method declarations do not. I can see others preferring CE, it's obviously meant for this use. – Kendall Helmstetter Gelner Oct 01 '08 at 05:08
-
3I really don't see (Private) as any more maintainable than (). If you're that worried then a good dose of comments might help. But obviously live and let live. YMMV etc. – schwa Oct 01 '08 at 05:18
-
17There is a rather important advantage to use `()` instead of `(Private)` (or some other category name): You can redeclare properties as readwrite while to the public they are only readonly. :) – Pascal Dec 04 '09 at 11:43
-
If you are in your object's main .m file, then using () allows you to place method definitions anywhere in the interface myObject section. If you declare as (Private), you get a warning if you don't put the definition in interface myObject (Private). – Walt Sellers Jan 12 '12 at 00:11
-
If you really want to write Private, then you can do `(/*Private*/)` and as it's a comment it's actually `()` and you can still declare properties – Jonathan. Apr 06 '12 at 09:15
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.

- 8,762
- 3
- 39
- 50

- 8,201
- 3
- 39
- 39
-
Looks like the link for "Cocoa's naming convention" has moved. Try http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994 – slothbear May 07 '09 at 18:10
-
1These autorelease bugs have bitten me many, many times in my short iPhone development career. Consciously avoiding the situations would have mitigated considerably. – bbrown May 14 '09 at 17:26
-
6I find the benefits of _not_ using autorelease outweighs its costs (i.e. more memory leak bugs). Code on the main thread should be fairly short-running anyway (or otherwise you'll freeze up the UI) and for longer-running, memory-intensive background code, you can always wrap the memory-intensive portions in local autorelease pools. – adib Jul 04 '10 at 23:27
-
56I disagree. You should use autoreleased objects whenever possible. If they increase the memory footprint by too much you should use another `NSAutoreleasePool`. But only after you confirmed that this really is an issue. Premature optimization and all that... – Sven Sep 05 '10 at 13:17
-
3I spend less than 40 sec. a day typing [someObject release] and reading the "extra line" when instantiating a new object, but I once burned through 17 hours to find an autorelease bug that would only show up in special cases and gave no coherent error in the console. So I agree with adib when he puts it like "I find the benefits of not using autorelease outweighs its costs". – RickiG Dec 08 '10 at 10:48
-
1There is nothing wrong with using AutoreleasePool as long as you get the ownership of the object; in your example I would use properties: self.aVariable=[AClass convenienceMethod]; in fact, Autoreleased objects are the very reason to use while returning from the methods; that is the advice given by Apple and Stanford iPhone course. – Özgür Dec 10 '10 at 05:00
-
7I agree with Sven. The primary goal should be code clarity and reducing coding errors, with memory optimization only where it is needed. Typing out a [[[Foo alloc] init] autorelease] is quick and you immediately deal with the issue of releasing this new object. When reading the code you don't have to hunt around for the corresponding release to make sure it isn't being leaked. – Mike Weller Dec 17 '10 at 18:42
-
3Lifecycle of autoreleased objects are well defined and determinable at enough level. – eonil Mar 29 '11 at 17:12
-
The lifecycle is typically one cycle of the event loop. That means that temporary objects can accumulate over the course of handling a tap, a swipe, or whatever. Per the original reply, allowing this to happen is not best practice, particularly when you can exercise more direct control. – mmalc Apr 07 '11 at 05:24
-
1The syntax of autoreleased provides much better code readability than the extra function calls of alloc init and the extra line for releasing. If your object doesn't get deallocated after a run loop cycle it means the object is retained by something else and wouldn't be dealloated even if you were releasing it "manually", the problem would not be "some autoreleasing bug"... – Zaky German Jun 10 '11 at 14:35
-
1@mmalc in the case where you are dealing with a lot of allocations within a single iteration of the runloop you can create a nested autorelease pool and drain that immediately. There is no need to be releasing objects manually. – brian Jun 23 '11 at 15:22
-
Avoiding autorelease as a matter of principle is a great way to make your code less maintainable, more error prone and harder to understand for no good reason (most of the time). – occulus Feb 14 '12 at 14:31
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.

- 40,399
- 3
- 75
- 82
-
3I'd suggest that you should put private methods in a class continuation. (i.e. @interface MyClass () ... @end in your .m) – Jason Medeiros Feb 07 '09 at 22:52
-
3Instead of #PRAGMA you can use a comment // Mark: [Section] which is more portable and works identically. – aleemb Jun 19 '09 at 12:26
-
Unless there's a special syntax I'm missing, // Mark: does not add a label in Xcode's functions drop down menu, which is really half the reason of using it. – Marc Charbonneau Jun 22 '09 at 15:21
-
6You need to use uppercase, "// MARK: ...", to get it to show up in the drop down. – Rhult Nov 21 '09 at 08:50
-
3In regards to `Finish what you start` you can also use `// TODO:` to mark code for completion which will show up in the drop down. – iwasrobbed Jul 12 '10 at 18:58
-
Once ivars are dynamically synthesized down the road (for iOS apps), you'll be glad you put IBOutlets in properties! – Joe D'Andrea Aug 30 '10 at 15:46
-
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.

- 54,380
- 8
- 73
- 102
-
-
13Xcode includes OCUnit, an Objective-C unit testing framework, and support for running bundles of unit tests as part of your build process. – Chris Hanson Jan 14 '09 at 06:50
Golden Rule: If you alloc
then you release
!
UPDATE: Unless you are using ARC

- 8,762
- 3
- 39
- 50

- 14,891
- 10
- 61
- 93
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.

- 37,782
- 12
- 108
- 140

- 54,380
- 8
- 73
- 102
-
10As a Java developer who has written an abstract factory in Objective-C I find this intriguing. Would you mind explaining a little more how this works - perhaps with an example? – teabot Jul 13 '09 at 12:51
-
2Do you still believe we don't need abstract factory classes after all the time that's past since you posted this answer? – kirk.burleson Jul 28 '10 at 20:35
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).

- 2,456
- 1
- 19
- 10
-
1There's now an iOS specific version of the [Debugging Magic](http://developer.apple.com/library/ios/#technotes/tn2239/_index.html) page. – Jeethu Aug 27 '11 at 09:05
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.

- 7,365
- 4
- 27
- 40

- 11,962
- 14
- 43
- 54
-
I like your answer, my advice would by do not use a category to store utility code unless you are about to replicate some code in more than one place and the code clearly belongs with the class you are about to categorfy... – Kendall Helmstetter Gelner Oct 01 '08 at 06:45
-
I'd just like to pipe in and voice my support for namespacing category methods. It just seems like the right thing to do. – Michael Buckley Oct 01 '08 at 07:43
-
-
14Counter-point: For the past year and a half I've followed the exact opposite policy: "If it can be implemented in a category, do so." As a result my code is much more concise, more expressive, and easier to read than the verbose sample code that Apple provides. I've lost a total of about 10 minutes to one namespace conflict, and I've probably gained man-months from the efficiencies I've created for myself. To each their own, but I adopted this policy knowing the risks, and I'm extremely glad that I did. – cduhn Apr 06 '10 at 08:05
-
7I don't agree. If it's going to be a function and it applies to a Foundation object, and you can think of a good name, stick it in a category. Your code will be more readable. I think that really the salient point here is: do everything in moderation. – mxcl Nov 04 '10 at 00:06
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.

- 54,380
- 8
- 73
- 102
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.

- 8,201
- 3
- 39
- 39
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.

- 8,762
- 3
- 39
- 50

- 8,201
- 3
- 39
- 39
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.
-
I have this: `#define SXRelease(o); o = nil` and the same for `CFRelease` and `free`. This simplifies everything. – Oct 25 '11 at 13:45
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.

- 51
- 2
- 3
-
1More info here: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html And here: http://stackoverflow.com/questions/2521275/what-is-nsparameterassert – Dave Jul 12 '10 at 18:40
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;
}
-
-
3This is only a concern when refraining from static typing. If the compiler knows the type, argument and return types can differ without problems. Personnaly, I find this not often to be a problem. Apple also has a lot of methods that have the same name but differ in return types. Finally, there's a compiler flag to warn you in ambiguous cases. – Nikolai Ruhe Aug 30 '10 at 21:21
-
If we follow Apple's naming convention guideline, this situation won't be happen :) – eonil Mar 29 '11 at 17:17
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.

- 2,456
- 1
- 19
- 10
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.

- 8,762
- 3
- 39
- 50

- 11,962
- 14
- 43
- 54
-
12
-
When using garbage collection, you are strongly discouraged from implementing a finalize method -- you should find other opportunities to clean up resources. – mmalc Oct 03 '08 at 15:53
-
1Apart from performance reasons (accessors are slightly slower than direct access) why shouldn't I use accessors in dealloc or init? – schwa Oct 10 '08 at 19:11
-
1(a) Performance reasons are perfectly adequate a reason in themselves (especially if your accessors are atomic). (b) You should avoid any side-effects that accessors may have. The latter is particularly an issue if your class may be subclassed. – mmalc Oct 11 '08 at 04:28
-
3I'll note that if you are running on the modern runtime with synthesized ivars you *must* use accessors in dealloc. A lot of modern runtime code is GC, but not all of it. – Louis Gerbarg Nov 10 '08 at 20:34
-
1A more extended view on wether or not to use accessor methods/properties in `-init` and `-dealloc` methods can be found here: http://www.mikeash.com/?page=pyblog/friday-qa-2009-11-27-using-accessors-in-init-and-dealloc.html – Johan Kool Nov 28 '09 at 07:49
-
1
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.

- 22,595
- 11
- 77
- 101
-
7Hmm, the first example is already full of bullshit. Never document language idioms. If I'd find those kinds of comments in a header file, I wouldn't bother reading on. – Stephan Eggermont Aug 15 '10 at 14:15
-
5
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.

- 2,456
- 1
- 19
- 10
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.

- 8,762
- 3
- 39
- 50

- 46,496
- 21
- 150
- 195
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.

- 2,456
- 1
- 19
- 10
-
6This is not true. Whether or not you are responsible for releasing top-level objects depends on what class you inherit from and what platform you are using. See http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemMgmtNibObjects.html amongst others. – mmalc Oct 03 '08 at 16:10
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.

- 19,298
- 7
- 47
- 66
-
And, if you can, turn on “Treat Warnings as Errors”. Allow no warning to exist. – Peter Hosey Oct 18 '09 at 23:14
-
2A handy script to setup your project with recommended warnings is available here: http://rentzsch.tumblr.com/post/237349423/hoseyifyxcodewarnings-scpt – Johan Kool Nov 28 '09 at 07:52
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.

- 128,090
- 22
- 218
- 270
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()
orCGAffineTransformMake()
. 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 readingview
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)

- 83,476
- 81
- 317
- 516
-
2As to 3) I'll propose the opposite approach: Use manual retain/release wherever possible! Who knows how this code will be used - and if it will be used in a tight loop it can blow up your memory usage unnecessarily. – Eiko May 18 '11 at 22:58
-
@Eiko That's just a [Premature Optimization](http://c2.com/cgi/wiki?PrematureOptimization), can't be general guidance. – eonil May 19 '11 at 02:34
-
1I think it's more a design thing, especially when working on model classes. I consider growing memory as a side effect, and that's not what I want to appear often. Worse, another developer who uses my code has no chance but to wrap expensive calls into autorelease pools (if possible at all - my objects might be sent to some other library code). And those problems are hard to diagnose later, but cheap to avoid in the first place. If you copy/autorelease objects that got passed in, you might be lost if they are much bigger than you expected. I am more relaxed with GUI code, though. – Eiko May 19 '11 at 08:49
-
@Eiko I agree `autorelease` will hold memory longer generally, and manual `retain/release` can reduce memory consumption in the case. However it should be guidance for special case optimization (even you're feeling always!), can't be the reason to generalize premature optimization as **practice**. And in fact, your suggestion is not opposite from me. I mentioned it as case of *really need* :) – eonil May 19 '11 at 09:48
The Apple-provided samples I saw treated the App delegate as a global data store, a data manager of sorts. That's wrongheaded. Create a singleton and maybe instantiate it in the App delegate, but stay away from using the App delegate as anything more than application-level event handling. I heartily second the recommendations in this blog entry. This thread tipped me off.
-
5Have you ever heard anyone tell you that the singleton is an anti-pattern? There is a reason for this....I'm disappointed that singletons are still viewed as the answer to all ills by cocoa programmers. – jkp Jun 06 '10 at 12:01
-
-1. The singleton is definitely an anti-pattern when you decide that your app needs more than one database (sync, multiple users, ...). – tc. Sep 23 '10 at 01:37
Only release a property in dealloc method. If you want to release memory that the property is holding, just set it as nil:
self.<property> = nil;

- 2,146
- 2
- 13
- 7
-
Note there is a great controversy about this. Using setter in `dealloc ` can produce a bug if you are not releasing properties in the correct order. However the same is valid when using `release` directly - another bugs can appear. Apple recommends using `release` in `dealloc` but they use setter in their implementation (e.g. releasing `delegate` in `[UITableView dealloc]`) – Sulthan Jan 07 '12 at 17:53
#import "MyClass.h"
@interface MyClass ()
- (void) someMethod;
- (void) someOtherMethod;
@end
@implementation MyClass

- 27,479
- 9
- 75
- 76

- 39
- 4