diff --git a/objcguide.xml b/objcguide.xml
new file mode 100644
index 0000000..554323d
--- /dev/null
+++ b/objcguide.xml
@@ -0,0 +1,1200 @@
+
+
+
+ Hooray! Now you know you can expand points to get more
+ details. Alternatively, there's an "expand all" at the
+ top of this document.
+ 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:
+
+ Greg Miller
+ Dave MacLachlan
+
+
+
+
+ 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 Google Toolbox for + Mac project (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 <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 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 ++ +
+ 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. +
+ ++ Even though Objective-C tends to be a more verbose language than C++, + to aid in the interoperability with that guide, we have decided + to keep the limit at 80 columns as well. It's easier to live with + than you might expect. +
+ ++ We recognize that this rule is controversial, but so much existing + code already adheres to it, and we feel that consistency is + important. +
++ You can make violations easier to spot in Xcode by going to Xcode + > Preferences > Text Editing > Show page guide. +
+ +-
or +
+ and the return type, and no spacing in the parameter list except between
+ parameters.
+ + Methods should look like this: +
++ The spacing before the asterisk is optional. When adding new code, + be consistent with the surrounding file's style. +
+
+ 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 :
before the parameter.
+
@public
and @private
access modifiers
+ should be indented by 1 space.
+
+ This is similar to public
, private
, and
+ protected
in C++.
+
@
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.
+ + If you must use Obj-C exceptions (please see Exceptions for reasons why you should + not be using exceptions) format them as follows: +
++ Naming rules are very import 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. +
++ 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.
+
+ File extensions should be as follows: +
+.h |
+ C/C++/Objective-C header file | +
.m |
+ Objective-C implementation file | +
.mm |
+ Objective-C++ implementation file | +
.cc |
+ Pure C++ implementation file | +
.c |
+ C implementation file | +
+ File names for categories should include the name of the class being
+ extended, e.g. GTMNSString+Utils.h
or
+ GTMNSTextView+Autocomplete.h
+
+ 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 @implementation
block, use
+ the Objective-C naming rules. If you're implementing a method for a
+ C++ class
, use the C++ naming rules.
+
+ In application-level 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. GTMSendMessage
).
+
+ For example, if we want to create a category on NSString
+ for parsing, we would put the category in a file named
+ GTMNSString+Parsing.h
, and the category itself would be
+ named GTMStringParsingAdditions
(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 (gtm_myCategoryMethodOnAString:
)
+ 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.
+
+ The method name should read like a sentence if possible, meaning you
+ should choose parameter names that flow with the method name. (e.g.
+ convertPoint:fromRect:
or
+ replaceCharactersInRange:withString:
). See Apple's
+ Guide to Naming Methods for more details.
+
+ Accessor methods should be named the same as the variable they're
+ "getting", but they should not be prefixed with the word
+ "get". For example:
+
+ This is for Objective-C methods only. C++ method names and functions + continue to follow the rules set in the C++ style guide. +
+ +@property
isn't
+ allowed.
+ + Do not 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: +
+
+ Instance variables are mixed case and should be suffixed with a
+ trailing underscore, e.g. usernameTextField_. However,
+ we permit an exception when binding to a member variable using
+ KVO/KVC and Objective-C 2.0 cannot be used (due to OS release
+ constraints). In this case, it is acceptable to prefix the variable
+ with an underscore, per Apple's accepted practices for key/value
+ naming. If Objective-C 2.0 can be used, @property
and
+ @synthesize
provide a solution that conforms to the
+ naming guidelines.
+
+ Constant names (#defines, enums, const local variables, etc.) should + start with a lowercase k and then use mixed case to + delimit words, i.e. kInvalidHandle, + kWritePerm. +
++ 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. +
+ ++ Every file should contain the following items, in order: +
Copyright 2008 Google Inc.
)+ If you make significant changes to a file that someone else + originally wrote, add yourself to the author line. This can + be very helpful when another + + contributor + has questions about the file and needs to know whom to contact + about it. +
++ 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. +
++ Additionally, each method in the public interface should have a + comment explaining its function, arguments, return value, and any + side effects. +
++ 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. +
+ ++ 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": +
++ or when quoting something which already contains quotes +
++ Instance variable pointers to objects derived from NSObject are + presumed to be retained, and should be documented as weak if + they are not retained by the class. However, instance variables which + are labeled as IBOutlets are presumed to not be retained by the class, + and should be documented as strong if the class does retain + them. +
++ Where instance variables are pointers to CoreFoundation, C++, and + other non-Objective-C objects, they should always be documented in + comments as strong or weak. Be mindful that support for automatic C++ + objects encapsulated in Objective-C objects is disabled by default, as + described here. +
+
+ Examples of strong and weak documentation:
+
retain
'd by this classretain
'd by this class
+ (e.g. a delegate).@private
.
+ + 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. +
+ +init...
method,
+ make sure you override the superclass' designated initializer.
+ + 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. +
+ +0
or nil
in the
+ init method; it's redundant.
+
+ All memory for a newly allocated object is initialized to 0 (except
+ for isa), so don't clutter up the init
method
+ by re-initializing variables to 0 or nil
.
+
+ 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. +
+
+ Before Objective-C 2.0, if you declare a method in the private
+ @interface
, but forget to implement it in the main
+ @implementation
, the compiler will not object.
+ (This is because you don't implement these private methods in a
+ separate category.) The solution is to put the functions within
+ an @implementation
that specifies the category.
+
+ If you are using Objective-C 2.0, you should instead declare your + private category using a class + extension, for example: +
+
+ which will guarantee that the declared methods are implemented in the
+ @implementation
section by issuing a compiler warning if
+ they are not.
+
+ 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. +
+
+ Finally, Objective-C categories are a great way to segment a large
+ @implementation
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
+ NSString
).
+
+ 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 #import
rather than
+ #include
.
+
autorelease
them on
+ the same line as you create them rather than a separate
+ release
later in the same method.
+
+ While ever so slightly slower, this prevents someone from accidentally
+ removing the release
or inserting a return
+ before it and introducing a memory leak. E.g.:
+
autorelease
then
+ retain
pattern.
+ + 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. +
+NSString
, should always copy
+ the string it accepts.
+
+ Never just retain
the string. This avoids the caller
+ changing it under you without your knowledge. Don't assume that
+ because you're accepting an NSString
that it's not
+ actually an NSMutableString
.
+
@throw
Objective-C exceptions, but you should be
+ prepared to catch them from third-party or OS calls.
+
+ We do compile with -fobjc-exceptions
(mainly so we get
+ @synchronized
), but we don't @throw
. Use of
+ @try
, @catch
, and @finally
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.
+
+ Do not use the NS_DURING
, NS_HANDLER
,
+ NS_ENDHANDLER
, NS_VALUERETURN
and
+ NS_VOIDRETURN
macros unless you are writing code that
+ needs to run on MacOS 10.2 or before.
+
+ Also be aware when writing Objective-C++ code that stack based objects + are not cleaned up when you throw an Objective-C exception. + Example: +
++ will give you: +
+
+ Note that the destructor for a never got called. This is a
+ major concern for stack based smartptrs such as
+ shared_ptr
and linked_ptr
, 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
+ std::string
, std::vector
etc.) allowed in
+ the body of any @try
, @catch
, or
+ @finally
blocks.
+
nil
checks for logic flow only.
+
+ Use nil
checks for logic flow of the application, not for
+ crash prevention. Sending a message to a nil
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
+ Apple's documentation for specifics).
+
+ Note that this is very different from checking C/C++ pointers against
+ NULL
, which the runtime does not handle and will cause
+ your application to crash. You still need to make sure you do not
+ dereference a NULL
pointer.
+
BOOL
return values and mixing
+ bool
with BOOL
. Avoid comparing directly
+ with YES
.
+
+ Only use the constants YES and NO for BOOL
return values
+ and assignments. Common mistakes include casting an array's size or
+ a pointer value as a BOOL, which depending on the value of the last
+ byte, could still result in a NO value.
+
+ Also be careful when interoperating with C++ and its bool
+ type. Don't just assume that YES
and NO
+ map directly to true
and false
. You can use
+ the ternary operator to succinctly map between them.
+
+ Finally, don't directly compare BOOL
variables directly
+ with YES
. Not only is is harder to read for those
+ well-versed in C, the first point above demonstrates that return
+ values may not always be what you expect.
+
+ A class that implements the delegate pattern should: +
delegate
+ and setDelegate:
.
+ @protocol
s for callback APIs.
+ +
protocol
for callback APIs where all the
+ methods must be implemented. Use a category
(or an
+ "informal protocol") when not all the methods need to be
+ implemented.
+