mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
c8c76a2389
- Clarify that sentence-like non-sentence comments are permitted. - Note that older code with incorrect #include ordering should be fixed. - Revamp the section on default function arguments. - Avoid explicitly recommending Init() methods. - C++11: permit "auto". - C++11: permit ">>" in place of "> >". - C++11: permit range-based "for". - C++11: permit variadic macros (already permitted as a C++03 extension). - C++11: permit "LL" and "ULL" literal suffixes (already permitted as a C++03 extension). - Reflect the revised copyright and author line policy: copyright notices are not required, but license boilerplate may still be used (and generally contains a copyright notice). Author lines are not required. - C++11: permit new features in <algorithm> and the portion of <numeric> that does not require initializer lists. - Revise rules on forward declarations: explicitly forbid forward-declared functions, do not mandate forward declarations, discourage forward-declared templates. - Remove the rule requiring "const" qualifiers for member functions to be on the same line as the closing parenthesis of the parameter list. - Fix typo: "unnamed namespaces." - C++11: permit local types as template parameters. - Fix typo: "unfamiliar." - Relax RTTI rules to permit its use, but warn about its abuse. - C++11: permit nullptr and nullptr_t. Revise text referring to NULL to refer more generically to null pointers. - Remove the "don't go crazy with const" rule. - Fix typo: "dir/foo2" should bee "dir2/foo2." - Remove reference to a specific GCC version. Update Objective-C style guide to 2.48: - Revise method declaration and invocation formatting rules for long names. - Reflect the revised copyright and author line policy: copyright notices are not required, but license boilerplate may still be used (and generally contains a copyright notice). Author lines are not required. Top-of-file comments are not required. - Fix dead link in the "nil Checks" section. - Cover ARC. - Specify that @private is only required for instance variables in header files. - Permit NSNumber literals. - Change the naming convention for instance variables from trailing underscore to leading underscore, allowing a wide exception for existing code and projects. - Fix description of BOOL with respect to its signedness. Update Python style guide to 2.45: - Recommend "pylint: disable" over "pylint: disable-msg." - Fix case-sensitive anchor. - Provide a better explanation of the problems with catch-all "except:." - Permit "map" and "filter" in absence of inlined lambdas. Update JavaScript style guide to 2.64: - Clarify rules for requiring and providing inner dependencies on classes. - Clarify semicolons for functions. - Note proper namespace and filename casing. - Fix typos: "@extends." - Permit parentheses to be omitted on unions. - Don't require method descriptions when obvious. - "in" is a keyword, put it in <code>. - New "Aliasing with goog.scope" section. - Rewrite the "Constants" section. - Remove the recommendation to use join() to build strings. - Add the "@expose" annotation. - Fix the "@suppress" example. - Remove reference alternate cast syntax. - Reflect the revised copyright and author line policy: copyright notices are not required, but license boilerplate may still be used (and generally contains a copyright notice). Author lines are not required. - Say that "use strict" is not required. - Fix links to "optional" section. - Rewrite "JavaScript Types" section. - Fix typos: "parameterizes," "converted." - Prefer in-constructor field initialization. - Add a section on "delete" and null-assignment. - Add a note about optional JSDoc comments on enum values. - State explicitly that dot operators belong at the ends of lines. - Add "@dict" and "@struct" annotations. - Add links to the JavaScript Types section. - Require (rather than encourage) compiling. Update HTML/CSS style guide to 2.19: - Rephrased quotation guidelines. - Updated W3C I18N article reference. - Fixed revision number. Update styleguide.xsl to 1.34: - Fix error in RefreshVisibilityFromHashParam when a URL fragment points to a named anchor within a section, as used by the JavaScript style guide.
1836 lines
64 KiB
XML
1836 lines
64 KiB
XML
<?xml version="1.0"?>
|
|
<?xml-stylesheet type="text/xsl" href="styleguide.xsl"?>
|
|
<GUIDE title="Google Objective-C Style Guide">
|
|
|
|
<p align="right">
|
|
|
|
Revision 2.48
|
|
</p>
|
|
|
|
|
|
|
|
<div align="right">
|
|
<address>
|
|
Mike Pinkerton<br/>
|
|
Greg Miller <br/>
|
|
Dave MacLachlan
|
|
</address>
|
|
</div>
|
|
|
|
<OVERVIEW>
|
|
|
|
<CATEGORY title="Important Note">
|
|
<STYLEPOINT title="Displaying Hidden Details in this Guide">
|
|
<SUMMARY>
|
|
This style guide contains many details that are initially
|
|
hidden from view. They are marked by the triangle icon, which you
|
|
see here on your left. Click it now.
|
|
You should see "Hooray" appear below.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
Hooray! Now you know you can expand points to get more
|
|
details. Alternatively, there's an "expand all" at the
|
|
top of this document.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
</CATEGORY>
|
|
|
|
<CATEGORY title="Background">
|
|
|
|
<p>
|
|
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.
|
|
</p>
|
|
|
|
<p>
|
|
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.
|
|
</p>
|
|
|
|
<p>
|
|
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:
|
|
<ul>
|
|
<li>
|
|
<a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/index.html">
|
|
Apple's Cocoa Coding Guidelines
|
|
</a>
|
|
</li>
|
|
<li>
|
|
|
|
<div>
|
|
<a href="http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml">
|
|
Google's Open Source C++ Style Guide
|
|
</a>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</p>
|
|
|
|
|
|
|
|
<p>
|
|
<em>Note that all things that are banned in Google's C++ guide are also
|
|
banned in Objective-C++, unless explicitly noted in this document.</em>
|
|
</p>
|
|
|
|
<p>
|
|
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.
|
|
</p>
|
|
|
|
<p>
|
|
Google has already released open-source code that conforms to these
|
|
guidelines as part of the
|
|
<a href="http://code.google.com/p/google-toolbox-for-mac/">
|
|
Google Toolbox for Mac project
|
|
</a>
|
|
(abbreviated GTM throughout this document).
|
|
Code meant to be shared across different projects is a good candidate to
|
|
be included in this repository.
|
|
</p>
|
|
|
|
|
|
|
|
<p>
|
|
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
|
|
<a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/index.html">
|
|
The Objective-C Programming Language
|
|
</a>.
|
|
</p>
|
|
</CATEGORY>
|
|
</OVERVIEW>
|
|
|
|
<CATEGORY title="Example">
|
|
|
|
<p>
|
|
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.
|
|
</p>
|
|
|
|
<p>
|
|
An example header file, demonstrating the correct commenting and spacing
|
|
for an <code>@interface</code> declaration
|
|
</p>
|
|
|
|
<CODE_SNIPPET>
|
|
#import <Foundation/Foundation.h>
|
|
|
|
// 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 Foo : NSObject {
|
|
@private
|
|
NSString *_bar;
|
|
NSString *_bam;
|
|
}
|
|
|
|
// Returns an autoreleased instance of Foo. See -initWithBar: for details
|
|
// about |bar|.
|
|
+ (id)fooWithBar:(NSString *)bar;
|
|
|
|
// Designated initializer. |bar| is a thing that represents a thing that
|
|
// does a thing.
|
|
- (id)initWithBar:(NSString *)bar;
|
|
|
|
// Gets and sets |_bar|.
|
|
- (NSString *)bar;
|
|
- (void)setBar:(NSString *)bar;
|
|
|
|
// Does some work with |blah| and returns YES if the work was completed
|
|
// successfully, and NO otherwise.
|
|
- (BOOL)doWorkWithBlah:(NSString *)blah;
|
|
|
|
@end
|
|
</CODE_SNIPPET>
|
|
|
|
<p>
|
|
An example source file, demonstrating the correct commenting and spacing
|
|
for the <code>@implementation</code> of an interface. It also includes the
|
|
reference implementations for important methods like getters and setters,
|
|
<code>init</code>, and <code>dealloc</code>.
|
|
</p>
|
|
|
|
<CODE_SNIPPET>
|
|
#import "Foo.h"
|
|
|
|
|
|
@implementation Foo
|
|
|
|
+ (id)fooWithBar:(NSString *)bar {
|
|
return [[[self alloc] initWithBar:bar] autorelease];
|
|
}
|
|
|
|
// Must always override super's designated initializer.
|
|
- (id)init {
|
|
return [self initWithBar:nil];
|
|
}
|
|
|
|
- (id)initWithBar:(NSString *)bar {
|
|
if ((self = [super init])) {
|
|
_bar = [bar copy];
|
|
_bam = [[NSString alloc] initWithFormat:@"hi %d", 3];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[_bar release];
|
|
[_bam release];
|
|
[super dealloc];
|
|
}
|
|
|
|
- (NSString *)bar {
|
|
return _bar;
|
|
}
|
|
|
|
- (void)setBar:(NSString *)bar {
|
|
[_bar autorelease];
|
|
_bar = [bar copy];
|
|
}
|
|
|
|
- (BOOL)doWorkWithBlah:(NSString *)blah {
|
|
// ...
|
|
return NO;
|
|
}
|
|
|
|
@end
|
|
</CODE_SNIPPET>
|
|
|
|
<p>
|
|
Blank lines before and after <code>@interface</code>,
|
|
<code>@implementation</code>, and <code>@end</code> are optional. If your
|
|
<code>@interface</code> declares instance variables, a blank
|
|
line should come after the closing brace (<code>}</code>).
|
|
<p>
|
|
</p>
|
|
Unless an interface or implementation is very short, such as when declaring
|
|
a handful of private methods or a bridge class, adding blank lines usually
|
|
helps readability.
|
|
</p>
|
|
|
|
</CATEGORY>
|
|
|
|
<CATEGORY title="Spacing And Formatting">
|
|
|
|
<STYLEPOINT title="Spaces vs. Tabs">
|
|
<SUMMARY>
|
|
Use only spaces, and indent 2 spaces at a time.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
We use spaces for indentation. Do not use tabs in your code.
|
|
You should set your editor to emit spaces when you hit the tab
|
|
key.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Line Length">
|
|
<SUMMARY>
|
|
Each line of text in your code should try to be at most 80 characters
|
|
long.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
Strive to keep your code within 80 columns. We realize that Objective C
|
|
is a verbose language and in some cases it may be more readable to
|
|
extend slightly beyond 80 columns, but this should definitely be the
|
|
exception and not commonplace.
|
|
</p>
|
|
<p>
|
|
If a reviewer asks that you reformat a line because they feel it can be
|
|
fit in 80 columns and still be readable, you should do so.
|
|
</p>
|
|
|
|
<p>
|
|
We recognize that this rule is controversial, but so much existing
|
|
code already adheres to it, and we feel that consistency is
|
|
important.
|
|
</p>
|
|
<p>
|
|
You can make violations easier to spot in Xcode by going to <i>Xcode
|
|
> Preferences > Text Editing > Show page guide</i>.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Method Declarations and Definitions">
|
|
<SUMMARY>
|
|
One space should be used between the <code>-</code> or <code>+</code>
|
|
and the return type, and no spacing in the parameter list except between
|
|
parameters.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
Methods should look like this:
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
- (void)doSomethingWithString:(NSString *)theString {
|
|
...
|
|
}
|
|
</CODE_SNIPPET>
|
|
<p>
|
|
The spacing before the asterisk is optional. When adding new code,
|
|
be consistent with the surrounding file's style.
|
|
</p>
|
|
<p>
|
|
If you have too many parameters to fit on one line, giving each its
|
|
own line is preferred. If multiple lines are used, align each using
|
|
the colon before the parameter.
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
- (void)doSomethingWith:(GTMFoo *)theFoo
|
|
rect:(NSRect)theRect
|
|
interval:(float)theInterval {
|
|
...
|
|
}
|
|
</CODE_SNIPPET>
|
|
<p>
|
|
When the first keyword is shorter than the others, indent the later
|
|
lines by at least four spaces, maintaining colon alignment:
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
- (void)short:(GTMFoo *)theFoo
|
|
longKeyword:(NSRect)theRect
|
|
evenLongerKeyword:(float)theInterval
|
|
error:(NSError **)theError {
|
|
...
|
|
}
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Method Invocations">
|
|
<SUMMARY>
|
|
Method invocations should be formatted much like method declarations.
|
|
When there's a choice of formatting styles, follow the convention
|
|
already used in a given source file.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
Invocations should have all arguments on one line:
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
[myObject doFooWith:arg1 name:arg2 error:arg3];
|
|
</CODE_SNIPPET>
|
|
<p>
|
|
or have one argument per line, with colons aligned:
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
[myObject doFooWith:arg1
|
|
name:arg2
|
|
error:arg3];
|
|
</CODE_SNIPPET>
|
|
<p>
|
|
Don't use any of these styles:
|
|
</p>
|
|
<BAD_CODE_SNIPPET>
|
|
[myObject doFooWith:arg1 name:arg2 // some lines with >1 arg
|
|
error:arg3];
|
|
|
|
[myObject doFooWith:arg1
|
|
name:arg2 error:arg3];
|
|
|
|
[myObject doFooWith:arg1
|
|
name:arg2 // aligning keywords instead of colons
|
|
error:arg3];
|
|
</BAD_CODE_SNIPPET>
|
|
|
|
<p>
|
|
As with declarations and definitions, when the first keyword is shorter
|
|
than the others, indent the later lines by at least four spaces,
|
|
maintaining colon alignment:
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
[myObj short:arg1
|
|
longKeyword:arg2
|
|
evenLongerKeyword:arg3
|
|
error:arg4];
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="@public and @private">
|
|
<SUMMARY>
|
|
The <code>@public</code> and <code>@private</code> access modifiers
|
|
should be indented by 1 space.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
This is similar to <code>public</code>, <code>private</code>, and
|
|
<code>protected</code> in C++.
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
@interface MyClass : NSObject {
|
|
@public
|
|
...
|
|
@private
|
|
...
|
|
}
|
|
@end
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Exceptions">
|
|
<SUMMARY>
|
|
Format exceptions with each <code>@</code> label on its own line and a
|
|
space between the <code>@</code> label and the opening brace
|
|
(<code>{</code>), as well as between the <code>@catch</code> and the
|
|
caught object declaration.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
If you must use Obj-C exceptions, format them as follows. However, see
|
|
<a href="#Avoid_Throwing_Exceptions">Avoid Throwing Exceptions</a> for
|
|
reasons why you <b>should not</b> be using exceptions.
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
@try {
|
|
foo();
|
|
}
|
|
@catch (NSException *ex) {
|
|
bar(ex);
|
|
}
|
|
@finally {
|
|
baz();
|
|
}
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Protocols">
|
|
<SUMMARY>
|
|
There should not be a space between the type identifier and the name
|
|
of the protocol encased in angle brackets.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
This applies to class declarations, instance variables, and method
|
|
declarations. For example:
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
@interface MyProtocoledClass : NSObject<NSWindowDelegate> {
|
|
@private
|
|
id<MyFancyDelegate> _delegate;
|
|
}
|
|
- (void)setDelegate:(id<MyFancyDelegate>)aDelegate;
|
|
@end
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Blocks">
|
|
<SUMMARY>
|
|
Blocks are preferred to the target-selector pattern when creating
|
|
callbacks, as it makes code easier to read. Code inside blocks should be
|
|
indented four spaces.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
There are several appropriate style rules, depending on how long the
|
|
block is:
|
|
</p>
|
|
<ul>
|
|
<li>If the block can fit on one line, no wrapping is necessary.</li>
|
|
<li>
|
|
If it has to wrap, the closing brace should line up with the first
|
|
character of the line on which the block is declared.
|
|
</li>
|
|
<li>Code within the block should be indented four spaces.</li>
|
|
<li>
|
|
If the block is large, e.g. more than 20 lines, it is recommended to
|
|
move it out-of-line into a local variable.
|
|
</li>
|
|
<li>
|
|
If the block takes no parameters, there are no spaces between the
|
|
characters <code>^{</code>. If the block takes parameters, there is no
|
|
space between the <code>^(</code> characters, but there is one space
|
|
between the <code>) {</code> characters.
|
|
</li>
|
|
<li>
|
|
Two space indents inside blocks are also allowed, but should only
|
|
be used when it's consistent with the rest of the project's code.
|
|
</li>
|
|
</ul>
|
|
<CODE_SNIPPET>
|
|
// The entire block fits on one line.
|
|
[operation setCompletionBlock:^{ [self onOperationDone]; }];
|
|
|
|
// The block can be put on a new line, indented four spaces, with the
|
|
// closing brace aligned with the first character of the line on which
|
|
// block was declared.
|
|
[operation setCompletionBlock:^{
|
|
[self.delegate newDataAvailable];
|
|
}];
|
|
|
|
// Using a block with a C API follows the same alignment and spacing
|
|
// rules as with Objective-C.
|
|
dispatch_async(_fileIOQueue, ^{
|
|
NSString* path = [self sessionFilePath];
|
|
if (path) {
|
|
// ...
|
|
}
|
|
});
|
|
|
|
// An example where the parameter wraps and the block declaration fits
|
|
// on the same line. Note the spacing of |^(SessionWindow *window) {|
|
|
// compared to |^{| above.
|
|
[[SessionService sharedService]
|
|
loadWindowWithCompletionBlock:^(SessionWindow *window) {
|
|
if (window) {
|
|
[self windowDidLoad:window];
|
|
} else {
|
|
[self errorLoadingWindow];
|
|
}
|
|
}];
|
|
|
|
// An example where the parameter wraps and the block declaration does
|
|
// not fit on the same line as the name.
|
|
[[SessionService sharedService]
|
|
loadWindowWithCompletionBlock:
|
|
^(SessionWindow *window) {
|
|
if (window) {
|
|
[self windowDidLoad:window];
|
|
} else {
|
|
[self errorLoadingWindow];
|
|
}
|
|
}];
|
|
|
|
// Large blocks can be declared out-of-line.
|
|
void (^largeBlock)(void) = ^{
|
|
// ...
|
|
};
|
|
[_operationQueue addOperationWithBlock:largeBlock];
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
</CATEGORY>
|
|
|
|
<CATEGORY title="Naming">
|
|
|
|
<p>
|
|
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. </p>
|
|
<p> When writing pure Objective-C code, we mostly follow standard <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html">Objective-C
|
|
naming rules</a>. 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.
|
|
</p>
|
|
<p>
|
|
Any class, category, method, or variable name may use all capitals for
|
|
<a href="http://en.wikipedia.org/wiki/Initialism">initialisms</a>
|
|
within the name. This follows Apple's standard of using all capitals
|
|
within a name for initialisms such as URL, TIFF, and EXIF.
|
|
</p>
|
|
<p>
|
|
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.
|
|
</p>
|
|
<p>
|
|
Our solution is that the style follows that of the method/function being
|
|
implemented. If you're in an <code>@implementation</code> block, use the
|
|
Objective-C naming rules. If you're implementing a method for a C++
|
|
<code>class</code>, 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.
|
|
</p>
|
|
|
|
<STYLEPOINT title="File Names">
|
|
<SUMMARY>
|
|
File names should reflect the name of the class implementation that
|
|
they contain—including case. Follow the convention that your
|
|
|
|
project
|
|
uses.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
File extensions should be as follows:
|
|
</p>
|
|
<table>
|
|
<tr>
|
|
<td><code>.h</code></td>
|
|
<td>C/C++/Objective-C header file</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>.m</code></td>
|
|
<td>Objective-C implementation file</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>.mm</code></td>
|
|
<td>Objective-C++ implementation file</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>.cc</code></td>
|
|
<td>Pure C++ implementation file</td>
|
|
</tr>
|
|
<tr>
|
|
<td><code>.c</code></td>
|
|
<td>C implementation file</td>
|
|
</tr>
|
|
</table>
|
|
<p>
|
|
File names for categories should include the name of the class being
|
|
extended, e.g. <code>GTMNSString+Utils.h</code> or
|
|
<code>GTMNSTextView+Autocomplete.h</code>
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Objective-C++">
|
|
<SUMMARY>
|
|
Within a source file, Objective-C++ follows the style of the
|
|
function/method you're implementing.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
In order to minimize clashes between the differing naming styles when
|
|
mixing Cocoa/Objective-C and C++, follow the style of the method being
|
|
implemented. If you're in an <code>@implementation</code> block, use
|
|
the Objective-C naming rules. If you're implementing a method for a
|
|
C++ <code>class</code>, use the C++ naming rules.
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
// file: cross_platform_header.h
|
|
|
|
class CrossPlatformAPI {
|
|
public:
|
|
...
|
|
int DoSomethingPlatformSpecific(); // impl on each platform
|
|
private:
|
|
int an_instance_var_;
|
|
};
|
|
|
|
// file: mac_implementation.mm
|
|
#include "cross_platform_header.h"
|
|
|
|
// A typical Objective-C class, using Objective-C naming.
|
|
@interface MyDelegate : NSObject {
|
|
@private
|
|
int _instanceVar;
|
|
CrossPlatformAPI* _backEndObject;
|
|
}
|
|
- (void)respondToSomething:(id)something;
|
|
@end
|
|
@implementation MyDelegate
|
|
- (void)respondToSomething:(id)something {
|
|
// bridge from Cocoa through our C++ backend
|
|
_instanceVar = _backEndObject->DoSomethingPlatformSpecific();
|
|
NSString* tempString = [NSString stringWithInt:_instanceVar];
|
|
NSLog(@"%@", tempString);
|
|
}
|
|
@end
|
|
|
|
// The platform-specific implementation of the C++ class, using
|
|
// C++ naming.
|
|
int CrossPlatformAPI::DoSomethingPlatformSpecific() {
|
|
NSString* temp_string = [NSString stringWithInt:an_instance_var_];
|
|
NSLog(@"%@", temp_string);
|
|
return [temp_string intValue];
|
|
}
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Class Names">
|
|
<SUMMARY>
|
|
Class names (along with category and protocol names) should start as
|
|
uppercase and use mixed case to delimit words.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
In <em>application-level</em> code, prefixes on class names should
|
|
generally be avoided. Having every single class with same prefix
|
|
impairs readability for no benefit. When designing code to be shared
|
|
across multiple applications, prefixes are acceptable and recommended
|
|
(e.g. <code>GTMSendMessage</code>).
|
|
</p>
|
|
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Category Names">
|
|
<SUMMARY>
|
|
Category names should start with a 2 or 3 character prefix
|
|
identifying the category as part of a project or open for general
|
|
use. The category name should incorporate the name of the class it's
|
|
extending.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
For example, if we want to create a category on <code>NSString</code>
|
|
for parsing, we would put the category in a file named
|
|
<code>GTMNSString+Parsing.h</code>, and the category itself would be
|
|
named <code>GTMStringParsingAdditions</code> (yes, we know the file
|
|
name and the category name do not match, but this file could have many
|
|
separate categories related to parsing). Methods in that category
|
|
should share the prefix (<code>gtm_myCategoryMethodOnAString:</code>)
|
|
in order to prevent collisions in Objective-C which only has a single
|
|
namespace. If the code isn't meant to be shared and/or doesn't run in
|
|
a different address-space, the method naming isn't quite as
|
|
important.
|
|
</p>
|
|
<p>
|
|
There should be a single space between the class name and the opening
|
|
parenthesis of the category.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Objective-C Method Names">
|
|
<SUMMARY>
|
|
Method names should start as lowercase and then use mixed case.
|
|
Each named parameter should also start as lowercase.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
The method name should read like a sentence if possible, meaning you
|
|
should choose parameter names that flow with the method name. (e.g.
|
|
<code>convertPoint:fromRect:</code> or
|
|
<code>replaceCharactersInRange:withString:</code>). See <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html#//apple_ref/doc/uid/20001282-BCIGIJJF">Apple's
|
|
Guide to Naming Methods</a> for more details.
|
|
</p>
|
|
<p>
|
|
Accessor methods should be named the same as the variable they're
|
|
"getting", but they should <em>not</em> be prefixed with the word
|
|
"get". For example:
|
|
<BAD_CODE_SNIPPET>
|
|
- (id)getDelegate; // AVOID
|
|
</BAD_CODE_SNIPPET>
|
|
<CODE_SNIPPET>
|
|
- (id)delegate; // GOOD
|
|
</CODE_SNIPPET>
|
|
</p>
|
|
<p>
|
|
This is for Objective-C methods only. C++ method names and functions
|
|
continue to follow the rules set in the C++ style guide.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Variable Names">
|
|
<SUMMARY>
|
|
Variables names start with a lowercase and use mixed case to delimit
|
|
words. Instance variables have leading underscores. For example:
|
|
<var>myLocalVariable</var>, <var>_myInstanceVariable</var>.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<SUBSECTION title="Common Variable Names">
|
|
<p>
|
|
Do <em>not</em> use Hungarian notation for syntactic attributes,
|
|
such as the static type of a variable (int or pointer). Give as
|
|
descriptive a name as possible, within reason. Don't worry about
|
|
saving horizontal space as it is far more important to make your
|
|
code immediately understandable by a new reader. For example:
|
|
</p>
|
|
<BAD_CODE_SNIPPET>
|
|
int w;
|
|
int nerr;
|
|
int nCompConns;
|
|
tix = [[NSMutableArray alloc] init];
|
|
obj = [someObject object];
|
|
p = [network port];
|
|
</BAD_CODE_SNIPPET>
|
|
<CODE_SNIPPET>
|
|
int numErrors;
|
|
int numCompletedConnections;
|
|
tickets = [[NSMutableArray alloc] init];
|
|
userInfo = [someObject object];
|
|
port = [network port];
|
|
</CODE_SNIPPET>
|
|
</SUBSECTION>
|
|
|
|
<SUBSECTION title="Instance Variables">
|
|
<p>
|
|
Instance variables are mixed case and should be prefixed with an
|
|
underscore e.g. <var>_usernameTextField</var>. Note that historically
|
|
the convention was to put the underscore at the end of the name, and
|
|
projects may opt to continue using trailing underscores in new code
|
|
in order to maintain consistency within their codebase (see the
|
|
Historical Notes section). It is recommended you leave old
|
|
code as-is, unless doing so would create inconsistency within a class.
|
|
</p>
|
|
</SUBSECTION>
|
|
|
|
<SUBSECTION title="Constants">
|
|
<p>
|
|
Constant names (#defines, enums, const local variables, etc.) should
|
|
start with a lowercase <var>k</var> and then use mixed case to
|
|
delimit words, i.e. <var>kInvalidHandle</var>,
|
|
<var>kWritePerm</var>.
|
|
</p>
|
|
</SUBSECTION>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
</CATEGORY>
|
|
|
|
<CATEGORY title="Comments">
|
|
|
|
<p>
|
|
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.
|
|
</p>
|
|
<p>
|
|
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!
|
|
</p>
|
|
<p>
|
|
Remember that all of the rules and conventions listed in the C++ Style
|
|
Guide are in effect here, with a few additional points, below.
|
|
</p>
|
|
|
|
<STYLEPOINT title="File Comments">
|
|
<SUMMARY>
|
|
A file may optionally start with a description of its contents.
|
|
</SUMMARY>
|
|
<BODY>
|
|
|
|
<p>
|
|
Every file should contain the following items, in order:
|
|
<ul>
|
|
<li>license boilerplate if neccessary. Choose the appropriate
|
|
boilerplate for the license used by the project (e.g.
|
|
Apache 2.0, BSD, LGPL, GPL).</li>
|
|
<li>a basic description of the contents of the file if necessary.</li>
|
|
</ul>
|
|
</p>
|
|
<p>
|
|
If you make significant changes to a file with an author line,
|
|
consider deleting the author line since revision history already
|
|
provides a more detailed and accurate record of authorship.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Declaration Comments">
|
|
<SUMMARY>
|
|
Every interface, category, and protocol declaration should have an
|
|
accompanying comment describing its purpose and how it fits into the
|
|
larger picture.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<CODE_SNIPPET>
|
|
// A delegate for NSApplication to handle notifications about app
|
|
// launch and shutdown. Owned by the main app controller.
|
|
@interface MyAppDelegate : NSObject {
|
|
...
|
|
}
|
|
@end
|
|
</CODE_SNIPPET>
|
|
<p>
|
|
If you have already described an interface in detail in the
|
|
comments at the top of your file feel free to simply state
|
|
"See comment at top of file for a complete description", but
|
|
be sure to have some sort of comment.
|
|
</p>
|
|
<p>
|
|
Additionally, each method in the public interface should have a
|
|
comment explaining its function, arguments, return value, and any
|
|
side effects.
|
|
</p>
|
|
<p>
|
|
Document the synchronization assumptions the class makes, if
|
|
any. If an instance of the class can be accessed by multiple
|
|
threads, take extra care to document the rules and invariants
|
|
surrounding multithreaded use.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Implementation Comments">
|
|
<SUMMARY>
|
|
Use vertical bars to quote variable names and symbols in comments rather
|
|
than quotes or naming the symbol inline.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
This helps eliminate ambiguity, especially when the symbol is a common
|
|
word that might make the sentence read like it was poorly constructed.
|
|
E.g. for a symbol "count":
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
// Sometimes we need |count| to be less than zero.
|
|
</CODE_SNIPPET>
|
|
<p>
|
|
or when quoting something which already contains quotes
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
// Remember to call |StringWithoutSpaces("foo bar baz")|
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Object Ownership">
|
|
<SUMMARY>
|
|
Make the pointer ownership model as explicit as possible when it falls
|
|
outside the most common Objective-C usage idioms.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<SUBSECTION title="Manual Reference Counting">
|
|
<p>
|
|
Instance variables which are pointers to objects derived from NSObject
|
|
are presumed to be retained, and should be either commented as weak or
|
|
declared with the <b>__weak</b> lifetime qualifier when applicable.
|
|
Similarly, declared properties must specify an <b>assign</b> property
|
|
attribute if they are not retained by the class. An exception is
|
|
instance variables labeled as IBOutlets in desktop Mac software,
|
|
which are presumed to not be retained.
|
|
</p>
|
|
<p>
|
|
Where instance variables are pointers to Core Foundation, C++, and
|
|
other non-Objective-C objects, they should always be declared with
|
|
the __strong or __weak type modifiers to indicate which pointers are
|
|
and are not retained. Core Foundation and other non-Objective-C object
|
|
pointers require explicit memory management, even when building for
|
|
automatic reference counting or garbage collection. When the __weak
|
|
type modifier is not allowed (e.g. C++ member variables when compiled
|
|
under clang), a comment should be used instead.
|
|
</p>
|
|
<p>
|
|
Be mindful that support for automatic C++ objects encapsulated in
|
|
Objective-C objects is disabled by default, as described <a href="http://chanson.livejournal.com/154253.html">
|
|
here</a>.
|
|
</p>
|
|
<p>
|
|
Examples of strong and weak declarations:
|
|
<CODE_SNIPPET>
|
|
@interface MyDelegate : NSObject {
|
|
@private
|
|
IBOutlet NSButton *_okButton; // normal NSControl; implicitly weak on Mac only
|
|
|
|
AnObjcObject* _doohickey; // my doohickey
|
|
__weak MyObjcParent *_parent; // so we can send msgs back (owns me)
|
|
|
|
// non-NSObject pointers...
|
|
__strong CWackyCPPClass *_wacky; // some cross-platform object
|
|
__strong CFDictionaryRef *_dict;
|
|
}
|
|
@property(strong, nonatomic) NSString *doohickey;
|
|
@property(weak, nonatomic) NSString *parent;
|
|
@end
|
|
</CODE_SNIPPET>
|
|
</p>
|
|
</SUBSECTION>
|
|
<SUBSECTION title="Automatic Reference Counting">
|
|
<p>
|
|
Object ownership and lifetime are explicit when using ARC, so no
|
|
additional comments are required.
|
|
</p>
|
|
</SUBSECTION>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
</CATEGORY>
|
|
|
|
<CATEGORY title="Cocoa and Objective-C Features">
|
|
|
|
<STYLEPOINT title="Instance Variables In Headers Should Be @private">
|
|
<SUMMARY>
|
|
Instance variables should be marked <code>@private</code> when they are
|
|
declared in a header file.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<CODE_SNIPPET>
|
|
@interface MyClass : NSObject {
|
|
@private
|
|
id _myInstanceVariable;
|
|
}
|
|
// public accessors, setter takes ownership
|
|
- (id)myInstanceVariable;
|
|
- (void)setMyInstanceVariable:(id)theVar;
|
|
@end
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Identify Designated Initializer">
|
|
<SUMMARY>
|
|
Comment and clearly identify your designated initializer.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
It is important for those who might be subclassing your class that the
|
|
designated initializer be clearly identified. That way, they only need
|
|
to subclass a single initializer (of potentially several) to guarantee
|
|
their subclass' initializer is called. It also helps those debugging
|
|
your class in the future understand the flow of initialization code if
|
|
they need to step through it.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Override Designated Initializer">
|
|
<SUMMARY>
|
|
When writing a subclass that requires an <code>init...</code> method,
|
|
make <i>sure</i> you override the superclass' designated initializer.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
If you fail to override the superclass' designated initializer, your
|
|
initializer may not be called in all cases, leading to subtle and
|
|
very difficult to find bugs.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Overridden NSObject Method Placement">
|
|
<SUMMARY>
|
|
It is strongly recommended and typical practice to place overridden
|
|
methods of <code>NSObject</code> at the top of an
|
|
<code>@implementation</code>.
|
|
</SUMMARY>
|
|
<BODY>
|
|
This commonly applies (but is not limited) to the <code>init...</code>,
|
|
<code>copyWithZone:</code>, and <code>dealloc</code> methods.
|
|
<code>init...</code> methods should be grouped together, followed by
|
|
the <code>copyWithZone:</code> method, and finally the
|
|
<code>dealloc</code> method.
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Initialization">
|
|
<SUMMARY>
|
|
Don't initialize variables to <code>0</code> or <code>nil</code> in the
|
|
init method; it's redundant.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
All memory for a newly allocated object is initialized to 0 (except
|
|
for <var>isa</var>), so don't clutter up the <code>init</code> method
|
|
by re-initializing variables to 0 or <code>nil</code>.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Avoid +new">
|
|
<SUMMARY>
|
|
Do not invoke the <code>NSObject</code> class method <code>new</code>,
|
|
nor override it in a subclass. Instead, use <code>alloc</code> and
|
|
<code>init</code> methods to instantiate retained objects.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
Modern Objective-C code explicitly calls <code>alloc</code> and an
|
|
<code>init</code> method to create and retain an object. As the
|
|
<code>new</code> class method is rarely used, it makes reviewing code
|
|
for correct memory management more difficult.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Keep the Public API Simple">
|
|
<SUMMARY>
|
|
Keep your class simple; avoid "kitchen-sink" APIs. If a method doesn't
|
|
need to be public, don't make it so. Use a private category to prevent
|
|
cluttering the public header.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
Unlike C++, Objective-C doesn't have a way to differentiate between
|
|
public and private methods—everything is public. As a result,
|
|
avoid placing methods in the public API unless they are actually
|
|
expected to be used by a consumer of the class. This helps reduce the
|
|
likelihood they'll be called when you're not expecting it. This includes
|
|
methods that are being overridden from the parent class. For internal
|
|
implementation methods, use a category defined in the implementation
|
|
file as opposed to adding them to the public header.
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
#import "GTMFoo.h"
|
|
|
|
@interface GTMFoo (PrivateDelegateHandling)
|
|
- (NSString *)doSomethingWithDelegate; // Declare private method
|
|
@end
|
|
|
|
@implementation GTMFoo(PrivateDelegateHandling)
|
|
...
|
|
- (NSString *)doSomethingWithDelegate {
|
|
// Implement this method
|
|
}
|
|
...
|
|
@end
|
|
</CODE_SNIPPET>
|
|
<p>
|
|
Before Objective-C 2.0, if you declare a method in the private
|
|
<code>@interface</code>, but forget to implement it in the main
|
|
<code>@implementation</code>, the compiler will <i>not</i> object.
|
|
(This is because you don't implement these private methods in a
|
|
separate category.) The solution is to put the functions within
|
|
an <code>@implementation</code> that specifies the category.
|
|
</p>
|
|
<p>
|
|
If you are using Objective-C 2.0, you should instead declare your
|
|
private category using a <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/chapter_4_section_5.html#">class
|
|
extension</a>, for example:
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
@interface GMFoo () { ... }
|
|
</CODE_SNIPPET>
|
|
<p>
|
|
which will guarantee that the declared methods are implemented in the
|
|
<code>@implementation</code> section by issuing a compiler warning if
|
|
they are not.
|
|
</p>
|
|
<p>
|
|
Again, "private" methods are not really private. You could
|
|
accidentally override a superclass's "private" method, thus making a
|
|
very difficult bug to squash. In general, private methods should have
|
|
a fairly unique name that will prevent subclasses from unintentionally
|
|
overriding them.
|
|
</p>
|
|
<p>
|
|
Finally, Objective-C categories are a great way to segment a large
|
|
<code>@implementation</code> section into more understandable chunks
|
|
and to add new, application-specific functionality to the most
|
|
appropriate class. For example, instead of adding "middle truncation"
|
|
code to a random object in your app, make a new category on
|
|
<code>NSString</code>).
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="#import and #include">
|
|
<SUMMARY>
|
|
<code>#import</code> Objective-C/Objective-C++ headers, and
|
|
<code>#include</code> C/C++ headers.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
Choose between <code>#import</code> and <code>#include</code> based
|
|
on the language of the header that you are including.
|
|
</p>
|
|
<ul>
|
|
<li>When including a header that uses Objective-C or Objective-C++,
|
|
use <code>#import</code>.</li>
|
|
<li>When including a standard C or C++ header, use
|
|
<code>#include</code>. The header should provide its own <a href="cppguide.xml?showone=The__define_Guard#The__define_Guard">#define
|
|
guard</a>.</li>
|
|
</ul>
|
|
<p>
|
|
Some Objective-C headers lack <code>#define</code> guards, and expect
|
|
to be included only by <code>#import</code>. As Objective-C headers
|
|
may only be included in Objective-C source files and other Objective-C
|
|
headers, using <code>#import</code> across the board is appropriate.
|
|
</p>
|
|
<p>
|
|
Standard C and C++ headers without any Objective-C in them can expect
|
|
to be included by ordinary C and C++ files. Since there is no
|
|
<code>#import</code> in standard C or C++, such files will be
|
|
included by <code>#include</code> in those cases. Using
|
|
<code>#include</code> for them in Objective-C source files as well
|
|
means that these headers will always be included with the same
|
|
semantics.
|
|
</p>
|
|
<p>
|
|
This rule helps avoid inadvertent errors in cross-platform
|
|
projects. A Mac developer introducing a new C or C++ header might
|
|
forget to add <code>#define</code> guards, which would not cause
|
|
problems on the Mac if the new header were included with
|
|
<code>#import</code>, but would break builds on other platforms
|
|
where <code>#include</code> is used. Being consistent by using
|
|
<code>#include</code> on all platforms means that compilation is
|
|
more likely to succeed everywhere or fail everywhere, and avoids
|
|
the frustration of files working only on some platforms.
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
#import <Cocoa/Cocoa.h>
|
|
#include <CoreFoundation/CoreFoundation.h>
|
|
#import "GTMFoo.h"
|
|
#include "base/basictypes.h"
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Use Root Frameworks">
|
|
<SUMMARY>
|
|
Include root frameworks over individual files.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
While it may seem tempting to include individual system headers from a
|
|
framework such as Cocoa or Foundation, in fact it's less work on the
|
|
compiler if you include the top-level root framework. The root
|
|
framework is generally pre-compiled and can be loaded much more
|
|
quickly. In addition, remember to use <code>#import</code> rather than
|
|
<code>#include</code> for Objective-C frameworks.
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
#import <Foundation/Foundation.h> // good
|
|
</CODE_SNIPPET>
|
|
<BAD_CODE_SNIPPET>
|
|
#import <Foundation/NSArray.h> // avoid
|
|
#import <Foundation/NSString.h>
|
|
...
|
|
</BAD_CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Prefer To autorelease At Time of Creation">
|
|
<SUMMARY>
|
|
When creating new temporary objects, <code>autorelease</code> them on
|
|
the same line as you create them rather than a separate
|
|
<code>release</code> later in the same method.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
While ever so slightly slower, this prevents someone from accidentally
|
|
removing the <code>release</code> or inserting a <code>return</code>
|
|
before it and introducing a memory leak. E.g.:
|
|
</p>
|
|
<BAD_CODE_SNIPPET>
|
|
// AVOID (unless you have a compelling performance reason)
|
|
MyController* controller = [[MyController alloc] init];
|
|
// ... code here that might return ...
|
|
[controller release];
|
|
</BAD_CODE_SNIPPET>
|
|
<CODE_SNIPPET>
|
|
// BETTER
|
|
MyController* controller = [[[MyController alloc] init] autorelease];
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Autorelease Then Retain">
|
|
<SUMMARY>
|
|
Assignment of objects follows the <code>autorelease</code> then
|
|
<code>retain</code> pattern.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
When assigning a new object to a variable, one must first release the
|
|
old object to avoid a memory leak. There are several "correct" ways to
|
|
handle this. We've chosen the "autorelease then retain" approach
|
|
because it's less prone to error. Be aware in tight loops it can fill
|
|
up the autorelease pool, and may be slightly less efficient, but we
|
|
feel the tradeoffs are acceptable.
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
- (void)setFoo:(GMFoo *)aFoo {
|
|
[_foo autorelease]; // Won't dealloc if |_foo| == |aFoo|
|
|
_foo = [aFoo retain];
|
|
}
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Avoid Accessors During init and dealloc">
|
|
<SUMMARY>
|
|
Instance subclasses may be in an inconsistent state during
|
|
<code>init</code> and <code>dealloc</code> method execution, so code in
|
|
those methods should avoid invoking accessors.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
Subclasses have not yet been initialized or have already deallocated
|
|
when <code>init</code> and <code>dealloc</code> methods execute, making
|
|
accessor methods potentially unreliable. Whenever practical, directly
|
|
assign to and release ivars in those methods rather than rely on
|
|
accessors.
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
- (id)init {
|
|
self = [super init];
|
|
if (self) {
|
|
_bar = [[NSMutableString alloc] init]; // good
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[_bar release]; // good
|
|
[super dealloc];
|
|
}
|
|
</CODE_SNIPPET>
|
|
<BAD_CODE_SNIPPET>
|
|
- (id)init {
|
|
self = [super init];
|
|
if (self) {
|
|
self.bar = [NSMutableString string]; // avoid
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc {
|
|
self.bar = nil; // avoid
|
|
[super dealloc];
|
|
}
|
|
</BAD_CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Dealloc Instance Variables in Declaration Order">
|
|
<SUMMARY>
|
|
<code>dealloc</code> should process instance variables in the same order
|
|
the <code>@interface</code> declares them, so it is easier for a reviewer
|
|
to verify.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
A code reviewer checking a new or revised <code>dealloc</code>
|
|
implementation needs to make sure that every retained instance
|
|
variable gets released.
|
|
</p>
|
|
<p>
|
|
To simplify reviewing <code>dealloc</code>, order the code so that
|
|
the retained instance variables get released in the same order that
|
|
they are declared in the <code>@interface</code>. If
|
|
<code>dealloc</code> invokes other methods that release instance
|
|
variables, add comments describing what instance variables those
|
|
methods handle.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Setters copy NSStrings">
|
|
<SUMMARY>
|
|
Setters taking an <code>NSString</code>, should always <code>copy</code>
|
|
the string it accepts.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
Never just <code>retain</code> the string. This avoids the caller
|
|
changing it under you without your knowledge. Don't assume that
|
|
because you're accepting an <code>NSString</code> that it's not
|
|
actually an <code>NSMutableString</code>.
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
- (void)setFoo:(NSString *)aFoo {
|
|
[_foo autorelease];
|
|
_foo = [aFoo copy];
|
|
}
|
|
</CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Avoid Throwing Exceptions">
|
|
<SUMMARY>
|
|
Don't <code>@throw</code> Objective-C exceptions, but you should be
|
|
prepared to catch them from third-party or OS calls.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
We do compile with <code>-fobjc-exceptions</code> (mainly so we get
|
|
<code>@synchronized</code>), but we don't <code>@throw</code>. Use of
|
|
<code>@try</code>, <code>@catch</code>, and <code>@finally</code> are
|
|
allowed when required to properly use 3rd party code or libraries. If
|
|
you do use them please document exactly which methods you expect to
|
|
throw.
|
|
</p>
|
|
<p>
|
|
Do not use the <code>NS_DURING</code>, <code>NS_HANDLER</code>,
|
|
<code>NS_ENDHANDLER</code>, <code>NS_VALUERETURN</code> and
|
|
<code>NS_VOIDRETURN</code> macros unless you are writing code that
|
|
needs to run on Mac OS X 10.2 or before.
|
|
</p>
|
|
<p>
|
|
Also be aware when writing Objective-C++ code that stack based objects
|
|
are <b>not</b> cleaned up when you throw an Objective-C exception.
|
|
Example:
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
class exceptiontest {
|
|
public:
|
|
exceptiontest() { NSLog(@"Created"); }
|
|
~exceptiontest() { NSLog(@"Destroyed"); }
|
|
};
|
|
|
|
void foo() {
|
|
exceptiontest a;
|
|
NSException *exception = [NSException exceptionWithName:@"foo"
|
|
reason:@"bar"
|
|
userInfo:nil];
|
|
@throw exception;
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
GMAutoreleasePool pool;
|
|
@try {
|
|
foo();
|
|
}
|
|
@catch(NSException *ex) {
|
|
NSLog(@"exception raised");
|
|
}
|
|
return 0;
|
|
}
|
|
</CODE_SNIPPET>
|
|
<p>
|
|
will give you:
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
2006-09-28 12:34:29.244 exceptiontest[23661] Created
|
|
2006-09-28 12:34:29.244 exceptiontest[23661] exception raised
|
|
</CODE_SNIPPET>
|
|
<p>
|
|
Note that the destructor for <i>a</i> never got called. This is a
|
|
major concern for stack based smartptrs such as
|
|
<code>shared_ptr</code> and <code>linked_ptr</code>, as well as any
|
|
STL objects that you may want to use. Therefore it pains us to say
|
|
that if you must use exceptions in your Objective-C++ code, use C++
|
|
exceptions whenever possible. You should never re-throw an Objective-C
|
|
exception, nor are stack based C++ objects (such as
|
|
<code>std::string</code>, <code>std::vector</code> etc.) allowed in
|
|
the body of any <code>@try</code>, <code>@catch</code>, or
|
|
<code>@finally</code> blocks.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
|
|
<STYLEPOINT title="nil Checks">
|
|
<SUMMARY>
|
|
Use <code>nil</code> checks for logic flow only.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
Use <code>nil</code> checks for logic flow of the application, not for
|
|
crash prevention. Sending a message to a <code>nil</code> object is
|
|
handled by the Objective-C runtime. If the method has no return
|
|
result, you're good to go. However if there is one, there may be
|
|
differences based on runtime architecture, return size, and OS X
|
|
version (see <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocObjectsClasses.html#//apple_ref/doc/uid/TP30001163-CH11-SW7">Apple's
|
|
documentation</a> for specifics).
|
|
</p>
|
|
<p>
|
|
Note that this is very different from checking C/C++ pointers against
|
|
<code>NULL</code>, which the runtime does not handle and will cause
|
|
your application to crash. You still need to make sure you do not
|
|
dereference a <code>NULL</code> pointer.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="BOOL Pitfalls">
|
|
<SUMMARY>
|
|
Be careful when converting general integral values to <code>BOOL</code>.
|
|
Avoid comparing directly with <code>YES</code>.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
<code>BOOL</code> is defined as a signed char in Objective-C which means
|
|
that it can have values other than <code>YES</code> (1) and
|
|
<code>NO</code> (0). Do not cast or convert general integral values
|
|
directly to <code>BOOL</code>. Common mistakes include casting or
|
|
converting an array's size, a pointer value, or the result of a bitwise
|
|
logic operation to a <code>BOOL</code> which, depending on the value of
|
|
the last byte of the integral result, could still result in a
|
|
<code>NO</code> value. When converting a general integral value to a
|
|
<code>BOOL</code> use ternery operators to return a <code>YES</code> or
|
|
<code>NO</code> value.
|
|
</p>
|
|
<p>
|
|
You can safely interchange and convert <code>BOOL</code>,
|
|
<code>_Bool</code> and <code>bool</code> (see C++ Std 4.7.4, 4.12 and
|
|
C99 Std 6.3.1.2). You cannot safely interchange <code>BOOL</code> and
|
|
<code>Boolean</code> so treat <code>Booleans</code> as a general
|
|
integral value as discussed above. Only use <code>BOOL</code> in
|
|
Objective C method signatures.
|
|
</p>
|
|
<p>
|
|
Using logical operators (<code>&&</code>, <code>||</code> and
|
|
<code>!</code>) with <code>BOOL</code> is also valid and will return
|
|
values that can be safely converted to <code>BOOL</code> without the
|
|
need for a ternery operator.
|
|
</p>
|
|
<BAD_CODE_SNIPPET>
|
|
- (BOOL)isBold {
|
|
return [self fontTraits] & NSFontBoldTrait;
|
|
}
|
|
- (BOOL)isValid {
|
|
return [self stringValue];
|
|
}
|
|
</BAD_CODE_SNIPPET>
|
|
<CODE_SNIPPET>
|
|
- (BOOL)isBold {
|
|
return ([self fontTraits] & NSFontBoldTrait) ? YES : NO;
|
|
}
|
|
- (BOOL)isValid {
|
|
return [self stringValue] != nil;
|
|
}
|
|
- (BOOL)isEnabled {
|
|
return [self isValid] && [self isBold];
|
|
}
|
|
</CODE_SNIPPET>
|
|
<p>
|
|
Also, don't directly compare <code>BOOL</code> variables directly
|
|
with <code>YES</code>. Not only is it harder to read for those
|
|
well-versed in C, the first point above demonstrates that return
|
|
values may not always be what you expect.
|
|
</p>
|
|
<BAD_CODE_SNIPPET>
|
|
BOOL great = [foo isGreat];
|
|
if (great == YES)
|
|
// ...be great!
|
|
</BAD_CODE_SNIPPET>
|
|
<CODE_SNIPPET>
|
|
BOOL great = [foo isGreat];
|
|
if (great)
|
|
// ...be great!
|
|
</CODE_SNIPPET>
|
|
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Properties">
|
|
<SUMMARY>
|
|
Use of the @property directive is preferred, with the following caveat:
|
|
properties are an Objective-C 2.0 feature which will limit your code to
|
|
running on the iPhone and Mac OS X 10.5 (Leopard) and higher. Dot notation
|
|
is allowed only for access to a declared <code>@property</code>.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<SUBSECTION title="Naming">
|
|
<p>
|
|
A property's associated instance variable's name must conform to the
|
|
leading _ requirement. The property's name should be the same as its
|
|
associated instance variable without the leading _. The optional space
|
|
between the <code>@property</code> and the opening parenthesis
|
|
should be omitted, as seen in the examples.
|
|
</p>
|
|
|
|
<CODE_SNIPPET>
|
|
@interface MyClass : NSObject
|
|
@property(copy, nonatomic) NSString *name;
|
|
@end
|
|
|
|
@implementation MyClass
|
|
// No code required for auto-synthesis, else use:
|
|
// @synthesize name = _name;
|
|
@end
|
|
</CODE_SNIPPET>
|
|
</SUBSECTION>
|
|
<SUBSECTION title="Location">
|
|
<p>
|
|
A property's declaration must come immediately after the instance
|
|
variable block of a class interface. A property's definition (if
|
|
not using automatic synthesis) must come immediately after the
|
|
<code>@implementation</code> block in a class definition. They are
|
|
indented at the same level as the <code>@interface</code> or
|
|
<code>@implementation</code> statements that they are enclosed in.
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
@interface MyClass : NSObject {
|
|
@private
|
|
NSString *_name;
|
|
}
|
|
@property(copy, nonatomic) NSString *name;
|
|
@end
|
|
|
|
@implementation MyClass
|
|
@synthesize name = _name;
|
|
|
|
- (id)init {
|
|
...
|
|
}
|
|
@end
|
|
</CODE_SNIPPET>
|
|
</SUBSECTION>
|
|
<SUBSECTION title="Use Copy Attribute For Strings">
|
|
<p>
|
|
NSString properties should always be declared with the
|
|
<code>copy</code> attribute.
|
|
</p>
|
|
<p>
|
|
This logically follows from the requirement that setters for
|
|
NSStrings always must use <code>copy</code> instead of
|
|
<code>retain</code>.
|
|
</p>
|
|
</SUBSECTION>
|
|
<SUBSECTION title="Atomicity">
|
|
<p>
|
|
Be aware of the overhead of properties. By default, all synthesized
|
|
setters and getters are atomic. This gives each set and get calls a
|
|
substantial amount of synchronization overhead. Declare your
|
|
properties <code>nonatomic</code> unless you require atomicity.
|
|
</p>
|
|
</SUBSECTION>
|
|
<SUBSECTION title="Dot notation">
|
|
<p>
|
|
Dot notation is idiomatic style for Objective-C 2.0. It may be used
|
|
when doing simple operations to get and set a <code>@property</code>
|
|
of an object, but should not be used to invoke other object behavior.
|
|
</p>
|
|
<CODE_SNIPPET>
|
|
NSString *oldName = myObject.name;
|
|
myObject.name = @"Alice";
|
|
</CODE_SNIPPET>
|
|
<BAD_CODE_SNIPPET>
|
|
NSArray *array = [[NSArray arrayWithObject:@"hello"] retain];
|
|
|
|
NSUInteger numberOfItems = array.count; // not a property
|
|
array.release; // not a property
|
|
</BAD_CODE_SNIPPET>
|
|
</SUBSECTION>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Interfaces Without Instance Variables">
|
|
<SUMMARY>
|
|
Omit the empty set of braces on interfaces that do not declare any
|
|
instance variables.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<CODE_SNIPPET>
|
|
@interface MyClass : NSObject
|
|
// Does a lot of stuff
|
|
- (void)fooBarBam;
|
|
@end
|
|
</CODE_SNIPPET>
|
|
<BAD_CODE_SNIPPET>
|
|
@interface MyClass : NSObject {
|
|
}
|
|
// Does a lot of stuff
|
|
- (void)fooBarBam;
|
|
@end
|
|
</BAD_CODE_SNIPPET>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Automatically Synthesized Instance Variables">
|
|
<SUMMARY>
|
|
<p>
|
|
Use of automatically synthesized instance variables is preferred. Code
|
|
that must support earlier versions of the compiler toolchain (Xcode 4.3
|
|
or earlier or when compiling with GCC) or is using properties inherited
|
|
from a protocol should prefer the @synthesize directive.
|
|
</p>
|
|
</SUMMARY>
|
|
<BODY>
|
|
<CODE_SNIPPET>
|
|
// Header file
|
|
@protocol Thingy
|
|
@property(nonatomic, copy) NSString *widgetName;
|
|
@end
|
|
|
|
@interface Foo : NSObject<Thingy>
|
|
// A guy walks into a bar.
|
|
@property(nonatomic, copy) NSString *bar;
|
|
@end
|
|
|
|
// Implementation file
|
|
@interface Foo ()
|
|
@property(nonatomic, retain) NSArray *baz;
|
|
@end
|
|
|
|
@implementation Foo
|
|
@synthesize widgetName = _widgetName;
|
|
@end
|
|
</CODE_SNIPPET>
|
|
|
|
<p>
|
|
Automatically synthesized instance variables take the form of the
|
|
property's name prefixed with an underscore and so typically conform to
|
|
the required variable naming style. If your property name is unusual,
|
|
or you are otherwise unable to use automatically synthesized instance
|
|
variables, use of the @synthesize directive is preferred, with the
|
|
instance variable name specified explicitly (as @synthesize does not add
|
|
a leading underscore by default).
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Automatic Reference Counting (ARC)">
|
|
<SUMMARY>
|
|
<p>
|
|
For projects that use Xcode 4.2 or later and will run only on 64-bit
|
|
Mac OS X 10.7 and iOS 5.0 and later, ARC is preferred. Use manual
|
|
reference counting when supporting earlier environments where zeroing
|
|
weak pointers are not available.
|
|
</p>
|
|
<p>
|
|
Classes that require ARC should include a preprocessor directive to
|
|
prevent compilation using manual reference counting.
|
|
</p>
|
|
<p>
|
|
Ownership qualifiers like <code>__unsafe_unretained</code> and
|
|
<code>__weak</code> should precede variable names. Specifying
|
|
<code>__strong</code> for variables is not required since it is
|
|
the default. Properties, on the other hand, should always specify the
|
|
<code>strong</code> keyword rather than relying on the compiler default.
|
|
</p>
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
Example of an implementation file enforcing ARC style. Note that
|
|
declaring instance variables in the @implementation is permitted when
|
|
using ARC.
|
|
<CODE_SNIPPET>
|
|
#if !defined(__has_feature) || !__has_feature(objc_arc)
|
|
#error "This file requires ARC support."
|
|
#endif
|
|
|
|
#import "Foo.h"
|
|
|
|
@implementation Foo {
|
|
@private
|
|
Bar * __weak _bar;
|
|
Baz * __unsafe_unretained _baz;
|
|
}
|
|
// ...
|
|
@end
|
|
</CODE_SNIPPET>
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="NSNumber Literals">
|
|
<SUMMARY>
|
|
<p>
|
|
For projects that use Xcode 4.4 or later with clang, the use of
|
|
<a href="http://clang.llvm.org/docs/ObjectiveCLiterals.html">NSNumber literals</a>
|
|
is allowed. Note however that this will limit the portability of your
|
|
code to other toolchains.
|
|
</p>
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
NSNumber literals are used just like Objective C string literals.
|
|
Boxing is used when necessary. Code using NSNumber literals can be
|
|
deployed on any iOS/MacOS system.
|
|
<CODE_SNIPPET>
|
|
NSNumber *fortyTwo = @42;
|
|
NSNumber *piOverTwo = @(M_PI / 2);
|
|
enum {
|
|
kMyEnum = 2;
|
|
};
|
|
NSNumber *myEnum = @(kMyEnum);
|
|
</CODE_SNIPPET>
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
</CATEGORY>
|
|
|
|
|
|
<CATEGORY title="Cocoa Patterns">
|
|
|
|
<STYLEPOINT title="Delegate Pattern">
|
|
<SUMMARY>
|
|
Delegate objects should not be retained.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
A class that implements the delegate pattern should:
|
|
<ol>
|
|
<li>
|
|
Have an instance variable named <var>_delegate</var> to reference
|
|
the delegate.
|
|
</li>
|
|
<li>
|
|
Thus, the accessor methods should be named <code>delegate</code>
|
|
and <code>setDelegate:</code>.
|
|
</li>
|
|
<li>
|
|
The <var>_delegate</var> object should <b>not</b> be retained.
|
|
</li>
|
|
</ol>
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
<STYLEPOINT title="Model/View/Controller">
|
|
<SUMMARY>
|
|
Separate the model from the view. Separate the controller from the
|
|
view and the model. Use <code>@protocol</code>s for callback APIs.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
<ul>
|
|
<li>
|
|
Separate model from view: don't build assumptions about the
|
|
presentation into the model or data source. Keep the interface
|
|
between the data source and the presentation abstract. Don't give
|
|
the model knowledge of its view. (A good rule of thumb is to ask
|
|
yourself if it's possible to have multiple presentations, with
|
|
different states, on a single instance of your data source.)
|
|
</li>
|
|
<li>
|
|
Separate controller from view and model: don't put all of the
|
|
"business logic" into view-related classes; this makes the code
|
|
very unusable. Make controller classes to host this code, but
|
|
ensure that the controller classes don't make too many assumptions
|
|
about the presentation.
|
|
</li>
|
|
<li>
|
|
Define callback APIs with <code>@protocol</code>, using
|
|
<code>@optional</code> if not all the methods are required.
|
|
(Exception: when using Objective-C 1.0, <code>@optional</code> isn't
|
|
available, so use a category to define an "informal protocol".)
|
|
</li>
|
|
</ul>
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
</CATEGORY>
|
|
|
|
<CATEGORY title="Historical Notes">
|
|
|
|
<STYLEPOINT title="Trailing vs Leading Underscores">
|
|
<SUMMARY>
|
|
Trailing underscores were once preferred for instance variable names.
|
|
</SUMMARY>
|
|
<BODY>
|
|
<p>
|
|
Our style guide used to have a rule saying that instance variables
|
|
should be named with a trailing underscore, similar to the naming of
|
|
member variables in C++. This was changed to leading underscores to
|
|
be consistent with the broader Objective-C community, to better follow
|
|
Apple's official guidelines, and to allow for use of new compiler
|
|
features like automatic instance variable synthesis. New projects are
|
|
strongly encouraged to use leading underscores. Existing projects may
|
|
continue to use trailing underscores in new code to maintain
|
|
consistency with the rest of their codebase.
|
|
</p>
|
|
</BODY>
|
|
</STYLEPOINT>
|
|
|
|
</CATEGORY>
|
|
|
|
<HR/>
|
|
|
|
<p align="right">
|
|
Revision 2.48
|
|
</p>
|
|
|
|
|
|
|
|
<address>
|
|
Mike Pinkerton <br/>
|
|
Greg Miller <br/>
|
|
Dave MacLachlan <br/>
|
|
</address>
|
|
</GUIDE>
|