分类: C/C++
2011-03-08 14:59:55
Objective-C is a very dynamic, object-oriented extension of C. It's designed to be easy to use and read, while enabling sophisticated object-oriented design. It is the primary development language for new applications on Mac OS X and the iPhone.
Cocoa is one of the main application frameworks on Mac OS X. It is a collection of Objective-C classes that provide for rapid development of full-featured Mac OS X applications.
Apple has already written a very good, and widely accepted, coding guide for Objective-C. Google has also written a similar guide for C++. This Objective-C guide aims to be a very natural combination of Apple's and Google's general recommendations. So, before reading this guide, please make sure you've read:
Note that all things that are banned in Google's C++ guide are also banned in Objective-C++, unless explicitly noted in this document.
The purpose of this document is to describe the Objective-C (and Objective-C++) coding guidelines and practices that should be used for all Mac OS X code. Many of these guidelines have evolved and been proven over time on other projects and teams. Open-source projects developed by Google conform to the requirements in this guide.
Google has already released open-source code that conforms to these guidelines as part of the (abbreviated GTM throughout this document). Code meant to be shared across different projects is a good candidate to be included in this repository.
Note that this guide is not an Objective-C tutorial. We assume that the reader is familiar with the language. If you are new to Objective-C or need a refresher, please read The Objective-C Programming Language .
They say an example is worth a thousand words so let's start off with an example that should give you a feel for the style, spacing, naming, etc.
An example header file, demonstrating the correct commenting and spacing for an @interface
declaration
// GTMFoo.h // FooProject // // Created by Greg Miller on 6/13/08. // Copyright 2008 Google, Inc. All rights reserved. // #import// A sample class demonstrating good Objective-C style. All interfaces, // categories, and protocols (read: all top-level declarations in a header) // MUST be commented. Comments must also be adjacent to the object they're // documenting. // // (no blank line between this comment and the interface) @interface GTMFoo : NSObject { @private NSString *foo_; NSString *bar_; } // Returns an autoreleased instance of GMFoo. See -initWithString: for details // about the argument. + (id)fooWithString:(NSString *)string; // Designated initializer. |string| will be copied and assigned to |foo_|. - (id)initWithString:(NSString *)string; // Gets and sets the string for |foo_|. - (NSString *)foo; - (void)setFoo:(NSString *)newFoo; // Does some work on |blah| and returns YES if the work was completed // successfuly, and NO otherwise. - (BOOL)doWorkWithString:(NSString *)blah; @end
An example source file, demonstating the correct commenting and spacing for the @implementation
of an interface. It also includes the reference implementations for important methods like getters and setters, init
, and dealloc
.
// // GTMFoo.m // FooProject // // Created by Greg Miller on 6/13/08. // Copyright 2008 Google, Inc. All rights reserved. // #import "GTMFoo.h" @implementation GTMFoo + (id)fooWithString:(NSString *)string { return [[[self alloc] initWithString:string] autorelease]; } // Must always override super's designated initializer. - (id)init { return [self initWithString:nil]; } - (id)initWithString:(NSString *)string { if ((self = [super init])) { foo_ = [string copy]; bar_ = [[NSString alloc] initWithFormat:@"hi %d", 3]; } return self; } - (void)dealloc { [foo_ release]; [bar_ release]; [super dealloc]; } - (NSString *)foo { return foo_; } - (void)setFoo:(NSString *)newFoo { [foo_ autorelease]; foo_ = [newFoo copy]; } - (BOOL)doWorkWithString:(NSString *)blah { // ... return NO; } @end
-
or +
and the return type, and no spacing in the parameter list except between parameters.@public
and @private
access modifiers should be indented by 1 space.@
label on its own line and a space between the @
label and the opening brace ({
), as well as between the @catch
and the caught object declaration.Naming rules are very important in maintainable code. Objective-C method names tend to be very long, but this has the benefit that a block of code can almost read like prose, thus rendering many comments unnecessary.
When writing pure Objective-C code, we mostly follow standard Objective-C naming rules. These naming guidelines may differ significantly from those outlined in the C++ style guide. For example, Google's C++ style guide recommends the use of underscores between words in variable names, whereas this guide recommends the use of intercaps, which is standard in the Objective-C community.
Any class, category, method, or variable name may use all capitals for within the name. This follows Apple's standard of using all capitals within a name for initialisms such as URL, TIFF, and EXIF.
When writing Objective-C++, however, things are not so cut and dry. Many projects need to implement cross-platform C++ APIs with some Objective-C or Cocoa, or bridge between a C++ back-end and a native Cocoa front-end. This leads to situations where the two guides are directly at odds.
Our solution is that the style follows that of the method/function being implemented. If you're in an @implementation
block, use the Objective-C naming rules. If you're implementing a method for a C++ class
, use the C++ naming rules. This avoids the situation where instance variable and local variable naming rules are mixed within a single function, which would be a serious detriment to readability.
@property
isn't allowed.Though a pain to write, they are absolutely vital to keeping our code readable. The following rules describe what you should comment and where. But remember: while comments are very important, the best code is self-documenting. Giving sensible names to types and variables is much better than using obscure names and then trying to explain them through comments.
When writing your comments, write for your audience: the next contributor who will need to understand your code. Be generous — the next one may be you!
Remember that all of the rules and conventions listed in the C++ Style Guide are in effect here, with a few additional points, below.
@private
.init...
method, make sure you override the superclass' designated initializer.0
or nil
in the init method; it's redundant.NSObject
class method new
, nor override it in a subclass. Instead, use alloc
and init
methods to instantiate retained objects.#import
Objective-C/Objective-C++ headers, and #include
C/C++ headers.autorelease
them on the same line as you create them rather than a separate release
later in the same method.autorelease
then retain
pattern.dealloc
should process instance variables in the same order the @interface
declares them, so it is easier for a reviewer to verify.NSString
, should always copy
the string it accepts.@throw
Objective-C exceptions, but you should be prepared to catch them from third-party or OS calls.nil
checks for logic flow only.BOOL
. Avoid comparing directly with YES
.@property
.@protocol
s for callback APIs.