From c5197bfc480154e85ac3be09cb4d0833427e09a7 Mon Sep 17 00:00:00 2001
From: Kevin Lindkvist
Date: Tue, 25 Jul 2017 19:21:16 -0700
Subject: [PATCH] =?UTF-8?q?[objc]=20Update=20the=20Objective-C=20style=20g?=
=?UTF-8?q?uide=20=F0=9F=93=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Revision Date: 8/16/2017
---
objcguide.md | 1606 +++++++++++++++++++++++++++++++++++++++++
objcguide.xml | 1884 -------------------------------------------------
2 files changed, 1606 insertions(+), 1884 deletions(-)
create mode 100644 objcguide.md
delete mode 100644 objcguide.xml
diff --git a/objcguide.md b/objcguide.md
new file mode 100644
index 000000000..fd4bb97ef
--- /dev/null
+++ b/objcguide.md
@@ -0,0 +1,1606 @@
+# Google Objective-C Style Guide
+
+> Objective-C is a 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 applications on OS X and on iOS.
+>
+> Apple has already written a very good, and widely accepted, [Cocoa Coding
+> Guidelines](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html)
+> for Objective-C. Please read it in addition to this guide.
+>
+>
+> The purpose of this document is to describe the Objective-C (and
+> Objective-C++) coding guidelines and practices that should be used for iOS and
+> OS X code. 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.
+>
+> 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 [Programming with
+> Objective-C](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html).
+
+
+## Example
+
+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, and so on.
+
+Here is an example header file, demonstrating the correct commenting and spacing
+for an `@interface` declaration.
+
+Doxygen-style comments are encouraged for interfaces as they are parsed by Xcode
+to display formatted documentation. There is a wide variety of Doxygen commands;
+use them consistently within a project.
+
+```objectivec
+// GOOD:
+
+#import
+
+@class Bar;
+
+/**
+ * A sample class demonstrating good Objective-C style. All interfaces,
+ * categories, and protocols (read: all non-trivial top-level declarations
+ * in a header) MUST be commented. Comments must also be adjacent to the
+ * object they're documenting.
+ */
+@interface Foo : NSObject
+
+/** The retained Bar. */
+@property(nonatomic) Bar *bar;
+
+/** The current drawing attributes. */
+@property(nonatomic, copy) NSDictionary *attributes;
+
+/**
+ * Convenience creation method.
+ * See -initWithBar: for details about @c bar.
+ *
+ * @param bar The string for fooing.
+ * @return An instance of Foo.
+ */
++ (instancetype)fooWithBar:(Bar *)bar;
+
+/**
+ * Designated initializer.
+ *
+ * @param bar A string that represents a thing that does a thing.
+ */
+- (instancetype)initWithBar:(Bar *)bar;
+
+/**
+ * Does some work with @c blah.
+ *
+ * @param blah
+ * @return YES if the work was completed; NO otherwise.
+ */
+- (BOOL)doWorkWithBlah:(NSString *)blah;
+
+@end
+```
+
+An example source file, demonstrating the correct commenting and spacing for the
+`@implementation` of an interface.
+
+```objectivec
+// GOOD:
+
+#import "Shared/Util/Foo.h"
+
+@implementation Foo {
+ // The string used for displaying "hi".
+ NSString *_string;
+}
+
++ (instancetype)fooWithBar:(Bar *)bar {
+ return [[self alloc] initWithBar:bar];
+}
+
+- (instancetype)init {
+ // Classes with a custom designated initializer should always override
+ // the superclass's designated initializer.
+ return [self initWithBar:nil];
+}
+
+- (instancetype)initWithBar:(Bar *)bar {
+ self = [super init];
+ if (self) {
+ _bar = [bar copy];
+ _string = [[NSString alloc] initWithFormat:@"hi %d", 3];
+ _attributes = @{
+ @"color" : [UIColor blueColor],
+ @"hidden" : @NO
+ };
+ }
+ return self;
+}
+
+- (BOOL)doWorkWithBlah:(NSString *)blah {
+ // Work should be done here.
+ return NO;
+}
+
+@end
+```
+
+## Spacing and Formatting
+
+### Spaces vs. Tabs
+
+Use only spaces, and indent 2 spaces at a time. 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, and to trim
+trailing spaces on lines.
+
+### Line Length
+
+The maximum line length for Objective-C files is 100 columns.
+
+You can make violations easier to spot by enabling *Preferences > Text Editing >
+Page guide at column: 100* in Xcode.
+
+### Method Declarations and Definitions
+
+One space should be used between the `-` or `+` and the return type, and no
+spacing in the parameter list except between parameters.
+
+Methods should look like this:
+
+```objectivec
+// GOOD:
+
+- (void)doSomethingWithString:(NSString *)theString {
+ ...
+}
+```
+
+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 colon before the
+parameter.
+
+```objectivec
+// GOOD:
+
+- (void)doSomethingWithFoo:(GTMFoo *)theFoo
+ rect:(NSRect)theRect
+ interval:(float)theInterval {
+ ...
+}
+```
+
+When the second or later parameter name is longer than the first, indent the
+second and later lines by at least four spaces, maintaining colon alignment:
+
+```objectivec
+// GOOD:
+
+- (void)short:(GTMFoo *)theFoo
+ longKeyword:(NSRect)theRect
+ evenLongerKeyword:(float)theInterval
+ error:(NSError **)theError {
+ ...
+}
+```
+
+### Conditionals
+
+Include a space after `if`, `while`, `for`, and `switch`, and around comparison
+operators.
+
+```objectivec
+// GOOD:
+
+for (int i = 0; i < 5; ++i) {
+}
+
+while (test) {};
+```
+
+Braces may be omitted when a loop body or conditional statement fits on a single
+line.
+
+```objectivec
+// GOOD:
+
+if (hasSillyName) LaughOutLoud();
+
+for (int i = 0; i < 10; i++) {
+ BlowTheHorn();
+}
+```
+
+```objectivec
+// AVOID:
+
+if (hasSillyName)
+ LaughOutLoud(); // AVOID.
+
+for (int i = 0; i < 10; i++)
+ BlowTheHorn(); // AVOID.
+```
+
+If an `if` clause has an `else` clause, both clauses should use braces.
+
+```objectivec
+// GOOD:
+
+if (hasBaz) {
+ foo();
+} else {
+ bar();
+}
+```
+
+```objectivec
+// AVOID:
+
+if (hasBaz) foo();
+else bar(); // AVOID.
+
+if (hasBaz) {
+ foo();
+} else bar(); // AVOID.
+```
+
+Intentional fall-through to the next case should be documented with a comment
+unless the case has no intervening code before the next case.
+
+```objectivec
+// GOOD:
+
+switch (i) {
+ case 1:
+ ...
+ break;
+ case 2:
+ j++;
+ // Falls through.
+ case 3: {
+ int k;
+ ...
+ break;
+ }
+ case 4:
+ case 5:
+ case 6: break;
+}
+```
+
+### Expressions
+
+Use a space around binary operators and assignments. Omit a space for a unary
+operator. Do not add spaces inside parentheses.
+
+```objectivec
+// GOOD:
+
+x = 0;
+v = w * x + y / z;
+v = -y * (x + z);
+```
+
+Factors in an expression may omit spaces.
+
+```objectivec
+// GOOD:
+
+v = w*x + y/z;
+```
+
+### Method Invocations
+
+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. Invocations should have all arguments on one line:
+
+```objectivec
+// GOOD:
+
+[myObject doFooWith:arg1 name:arg2 error:arg3];
+```
+
+or have one argument per line, with colons aligned:
+
+```objectivec
+// GOOD:
+
+[myObject doFooWith:arg1
+ name:arg2
+ error:arg3];
+```
+
+Don't use any of these styles:
+
+```objectivec
+// AVOID:
+
+[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];
+```
+
+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:
+
+```objectivec
+// GOOD:
+
+[myObj short:arg1
+ longKeyword:arg2
+ evenLongerKeyword:arg3
+ error:arg4];
+```
+
+Invocations containing multiple inlined blocks may have their parameter names
+left-aligned at a four space indent.
+
+### Function Calls
+
+Function calls should include as many parameters as fit on each line, except
+where shorter lines are needed for clarity or documentation of the parameters.
+
+Continuation lines for function parameters may be indented to align with the
+opening parenthesis, or may have a four-space indent.
+
+```objectivec
+// GOOD:
+
+CFArrayRef array = CFArrayCreate(kCFAllocatorDefault, objects, numberOfObjects,
+ &kCFTypeArrayCallBacks);
+
+NSString *string = NSLocalizedStringWithDefaultValue(@"FEET", @"DistanceTable",
+ resourceBundle, @"%@ feet", @"Distance for multiple feet");
+
+UpdateTally(scores[x] * y + bases[x], // Score heuristic.
+ x, y, z);
+
+TransformImage(image,
+ x1, x2, x3,
+ y1, y2, y3,
+ z1, z2, z3);
+```
+
+Use local variables with descriptive names to shorten function calls and reduce
+nesting of calls.
+
+```objectivec
+// GOOD:
+
+double scoreHeuristic = scores[x] * y + bases[x];
+UpdateTally(scoreHeuristic, x, y, z);
+```
+
+### Exceptions
+
+Format exceptions with `@catch` and `@finally` labels on the same line as the
+preceding `}`. Add a space between the `@` label and the opening brace (`{`), as
+well as between the `@catch` and the caught object declaration. If you must use
+Objective-C exceptions, format them as follows. However, see Avoid Throwing
+Exceptions for reasons why you should not be using exceptions.
+
+```objectivec
+// GOOD:
+
+@try {
+ foo();
+} @catch (NSException *ex) {
+ bar(ex);
+} @finally {
+ baz();
+}
+```
+
+### Function Length
+
+Prefer small and focused functions.
+
+Long functions and methods are occasionally appropriate, so no hard limit is
+placed on function length. If a function exceeds about 40 lines, think about
+whether it can be broken up without harming the structure of the program.
+
+Even if your long function works perfectly now, someone modifying it in a few
+months may add new behavior. This could result in bugs that are hard to find.
+Keeping your functions short and simple makes it easier for other people to read
+and modify your code.
+
+When updating legacy code, consider also breaking long functions into smaller
+and more manageable pieces.
+
+### Vertical Whitespace
+
+Use vertical whitespace sparingly.
+
+To allow more code to be easily viewed on a screen, avoid putting blank lines
+just inside the braces of functions.
+
+Limit blank lines to one or two between functions and between logical groups of
+code.
+
+## Naming
+
+Names should be as descriptive as possible, within reason. Follow standard
+[Objective-C naming
+rules](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html).
+
+Avoid non-standard abbreviations. 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:
+
+```objectivec
+// GOOD:
+
+// Good names.
+int numberOfErrors = 0;
+int completedConnectionsCount = 0;
+tickets = [[NSMutableArray alloc] init];
+userInfo = [someObject object];
+port = [network port];
+NSDate *gAppLaunchDate;
+```
+
+```objectivec
+// AVOID:
+
+// Names to avoid.
+int w;
+int nerr;
+int nCompConns;
+tix = [[NSMutableArray alloc] init];
+obj = [someObject object];
+p = [network port];
+```
+
+Any class, category, method, function, or variable name should use all capitals
+for acronyms and
+[initialisms](https://en.wikipedia.org/wiki/Initialism)
+within the name. This follows Apple's standard of using all capitals within a
+name for acronyms such as URL, ID, TIFF, and EXIF.
+
+Names of C functions and typedefs should be capitalized and use camel case as
+appropriate for the surrounding code.
+
+### File Names
+
+File names should reflect the name of the class implementation that they
+contain—including case.
+
+Follow the convention that your project uses.
+File extensions should be as follows:
+
+Extension | Type
+--------- | ---------------------------------
+.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
+
+Files containing code that may be shared across projects or used in a large
+project should have a clearly unique name, typically including the project or
+class prefix.
+
+File names for categories should include the name of the class being extended,
+like GTMNSString+Utils.h or NSTextView+GTMAutocomplete.h
+
+### Class Names
+
+Class names (along with category and protocol names) should start as uppercase
+and use mixed case to delimit words.
+
+When designing code to be shared across multiple applications, prefixes are
+acceptable and recommended (e.g. GTMSendMessage). Prefixes are also recommended
+for classes of large applications that depend on external libraries.
+
+### Category Names
+
+Category names should start with a 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. For
+example, if we want to create a category on `NSString` for parsing, we would put
+the category in a file named `NSString+GTMParsing.h`, and the category itself
+would be named `GTMNSStringParsingAdditions`. The file name and the category may
+not match, as 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's global namespace.
+
+There should be a single space between the class name and the opening
+parenthesis of the category.
+
+```objectivec
+// GOOD:
+
+// Using a category to extend a Foundation class.
+@interface NSString (GTMNSStringParsingAdditions)
+- (NSString *)gtm_parsedString;
+@end
+```
+
+### Objective-C Method Names
+
+Method and parameter names typically start as lowercase and then use mixed case.
+
+Proper capitalization should be respected, including at the beginning of names.
+
+```objectivec
+// GOOD:
+
++ (NSURL *)URLWithString;
+```
+
+The method name should read like a sentence if possible, meaning you should
+choose parameter names that flow with the method name. 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 implementation comments unnecessary.
+
+Use prepositions and conjunctions like "with", "from", and "to" in the second
+and later parameter names only where necessary to clarify the meaning or
+behavior of the method.
+
+```objectivec
+// GOOD:
+
+- (void)addTarget:(id)target action:(SEL)action; // GOOD; no conjunction needed
+- (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view; // GOOD; conjunction clarifies parameter
+- (void)replaceCharactersInRange:(NSRange)aRange
+ withAttributedString:(NSAttributedString *)attributedString; // GOOD.
+```
+
+A method that returns an object should have a name beginning with a noun
+identifying the object returned:
+
+```objectivec
+// GOOD:
+
+- (Sandwich *)sandwich; // GOOD.
+```
+
+```objectivec
+// AVOID:
+
+- (Sandwich *)makeSandwich; // AVOID.
+```
+
+An accessor method should be named the same as the object it's getting, but it
+should not be prefixed with the word `get`. For example:
+
+```objectivec
+// GOOD:
+
+- (id)delegate; // GOOD.
+```
+
+```objectivec
+// AVOID:
+
+- (id)getDelegate; // AVOID.
+```
+
+Accessors that return the value of boolean adjectives have method names
+beginning with `is`, but property names for those methods omit the `is`.
+
+Dot notation is used only with property names, not with method names.
+
+```objectivec
+// GOOD:
+
+@property(nonatomic, getter=isGlorious) BOOL glorious;
+- (BOOL)isGlorious;
+
+BOOL isGood = object.glorious; // GOOD.
+BOOL isGood = [object isGlorious]; // GOOD.
+```
+
+```objectivec
+// AVOID:
+
+BOOL isGood = object.isGlorious; // AVOID.
+```
+
+```objectivec
+// GOOD:
+
+NSArray *frogs = [NSArray arrayWithObject:frog];
+NSEnumerator *enumerator = [frogs reverseObjectEnumerator]; // GOOD.
+```
+
+```objectivec
+// AVOID:
+
+NSEnumerator *enumerator = frogs.reverseObjectEnumerator; // AVOID.
+```
+
+See [Apple's Guide to Naming
+Methods](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html#//apple_ref/doc/uid/20001282-BCIGIJJF)
+for more details on Objective-C naming.
+
+These guidelines are for Objective-C methods only. C++ method names continue to
+follow the rules set in the C++ style guide.
+
+### Function Names
+
+Regular functions have mixed case.
+
+Ordinarily, functions should start with a capital letter and have a capital
+letter for each new word (a.k.a. "[Camel
+Case](https://en.wikipedia.org/wiki/Camel_case)" or "Pascal case").
+
+```objectivec
+// GOOD:
+
+static void AddTableEntry(NSString *tableEntry);
+static BOOL DeleteFile(char *filename);
+```
+
+Because Objective-C does not provide namespacing, non-static functions should
+have a prefix that minimizes the chance of a name collision.
+
+```objectivec
+// GOOD:
+
+extern NSTimeZone *GTMGetDefaultTimeZone();
+extern NSString *GTMGetURLScheme(NSURL *URL);
+```
+
+### Variable Names
+
+Variable names typically start with a lowercase and use mixed case to delimit
+words.
+
+Instance variables have leading underscores. File scope or global variables have
+a prefix `g`. For example: `myLocalVariable`, `_myInstanceVariable`,
+`gMyGlobalVariable`.
+
+#### Common Variable Names
+
+Readers should be able to infer the variable type from the name, but do not use
+Hungarian notation for syntactic attributes, such as the static type of a
+variable (int or pointer).
+
+File scope or global variables (as opposed to constants) declared outside the
+scope of a method or function should be rare, and should have the prefix g.
+
+```objectivec
+// GOOD:
+
+static int gGlobalCounter;
+```
+
+#### Instance Variables
+
+Instance variable names are mixed case and should be prefixed with an
+underscore, like `_usernameTextField`.
+
+NOTE: Google's previous convention for Objective-C ivars was a trailing
+underscore. Existing projects may opt to continue using trailing underscores in
+new code in order to maintain consistency within the project codebase.
+Consistency of prefix or suffix underscores should be maintained within each
+class.
+
+#### Constants
+
+Constant symbols (const global and static variables and constants created
+with #define) should use mixed case to delimit words.
+
+Constants should have an appropriate prefix.
+
+```objectivec
+// GOOD:
+
+extern NSString *const GTLServiceErrorDomain;
+
+typedef NS_ENUM(NSInteger, GTLServiceError) {
+ GTLServiceErrorQueryResultMissing = -3000,
+ GTLServiceErrorWaitTimedOut = -3001,
+};
+```
+
+Because Objective-C does not provide namespacing, constants with external
+linkage should have a prefix that minimizes the chance of a name collision,
+typically like `ClassNameConstantName` or `ClassNameEnumName`.
+
+For interoperability with Swift code, enumerated values should have names that
+extend the typedef name:
+
+```objectivec
+// GOOD:
+
+typedef NS_ENUM(NSInteger, DisplayTinge) {
+ DisplayTingeGreen = 1,
+ DisplayTingeBlue = 2,
+};
+```
+
+Constants may use a lowercase k prefix when appropriate:
+
+```objectivec
+// GOOD:
+
+static const int kFileCount = 12;
+static NSString *const kUserKey = @"kUserKey";
+```
+
+## Types and Declarations
+
+### Local Variables
+
+Declare variables in the narrowest practical scopes, and close to their use.
+Initialize variables in their declarations.
+
+```objectivec
+// GOOD:
+
+CLLocation *location = [self lastKnownLocation];
+for (int meters = 1; meters < 10; meters++) {
+ reportFrogsWithinRadius(location, meters);
+}
+```
+
+Occasionally, efficiency will make it more appropriate to declare a variable
+outside the scope of its use. This example declares meters separate from
+initialization, and needlessly sends the lastKnownLocation message each time
+through the loop:
+
+```objectivec
+// AVOID:
+
+int meters; // AVOID.
+for (meters = 1; meters < 10; meters++) {
+ CLLocation *location = [self lastKnownLocation]; // AVOID.
+ reportFrogsWithinRadius(location, meters);
+}
+```
+
+Under Automatic Reference Counting, pointers to Objective-C objects are by
+default initialized to `nil`, so explicit initialization to `nil` is not
+required.
+
+### Unsigned Integers
+
+Avoid unsigned integers except when matching types used by system interfaces.
+
+Subtle errors crop up when doing math or counting down to zero using unsigned
+integers. Rely only on signed integers in math expressions except when matching
+NSUInteger in system interfaces.
+
+```objectivec
+// GOOD:
+
+NSUInteger numberOfObjects = array.count;
+for (NSInteger counter = numberOfObjects - 1; counter > 0; --counter)
+```
+
+```objectivec
+// AVOID:
+
+for (NSUInteger counter = numberOfObjects - 1; counter > 0; --counter) // AVOID.
+```
+
+Unsigned integers may be used for flags and bitmasks, though often NS_OPTIONS or
+NS_ENUM will be more appropriate.
+
+### Types with Inconsistent Sizes
+
+Due to sizes that differ in 32- and 64-bit builds, avoid types long, NSInteger,
+NSUInteger, and CGFloat except when matching system interfaces.
+
+Types long, NSInteger, NSUInteger, and CGFloat vary in size between 32- and
+64-bit builds. Use of these types is appropriate when handling values exposed by
+system interfaces, but they should be avoided for most other computations.
+
+```objectivec
+// GOOD:
+
+int32_t scalar1 = proto.intValue;
+
+int64_t scalar2 = proto.longValue;
+
+NSUInteger numberOfObjects = array.count;
+
+CGFloat offset = view.bounds.origin.x;
+```
+
+```objectivec
+// AVOID:
+
+NSInteger scalar2 = proto.longValue; // AVOID.
+```
+
+File and buffer sizes often exceed 32-bit limits, so they should be declared
+using `int64_t`, not with `long`, `NSInteger`, or `NSUInteger`.
+
+## Comments
+
+Comments are absolutely vital to keeping our code readable. The following rules
+describe what you should comment and where. But remember: while comments are
+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.
+
+Pay attention to punctuation, spelling, and grammar; it is easier to read
+well-written comments than badly written ones.
+
+Comments should be as readable as narrative text, with proper capitalization and
+punctuation. In many cases, complete sentences are more readable than sentence
+fragments. Shorter comments, such as comments at the end of a line of code, can
+sometimes be less formal, but use a consistent style.
+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!
+
+### File Comments
+
+A file may optionally start with a description of its contents.
+Every file may contain the following items, in order:
+ * License boilerplate if necessary. Choose the appropriate boilerplate for the license used by the project.
+ * A basic description of the contents of the file if necessary.
+
+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.
+
+
+### Declaration Comments
+
+Every non-trivial interface, public and private, should have an accompanying
+comment describing its purpose and how it fits into the larger picture.
+
+Comments should be used to document classes, properties, ivars, functions,
+categories, protocol declarations, and enums.
+
+```objectivec
+// GOOD:
+
+/**
+ * A delegate for NSApplication to handle notifications about app
+ * launch and shutdown. Owned by the main app controller.
+ */
+@interface MyAppDelegate : NSObject {
+ /**
+ * The background task in progress, if any. This is initialized
+ * to the value UIBackgroundTaskInvalid.
+ */
+ UIBackgroundTaskIdentifier _backgroundTaskID;
+}
+
+/** The factory that creates and manages fetchers for the app. */
+@property(nonatomic) GTMSessionFetcherService *fetcherService;
+
+@end
+```
+
+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 should have a comment explaining its function,
+arguments, return value, thread or queue assumptions, and any side effects.
+Documentation comments should be in the header for public methods, or
+immediately preceding the method for non-trivial private methods.
+
+Use descriptive form ("Opens the file") rather than imperative form ("Open the
+file") for method and function comments. The comment describes the function; it
+does not tell the function what to do.
+
+Document the thread usage assumptions the class, properties, or methods make, 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.
+
+Any sentinel values for properties and ivars, such as `NULL` or `-1`, should be
+documented in comments.
+
+Declaration comments explain how a method or function is used. Comments
+explaining how a method or function is implemented should be with the
+implementation rather than with the declaration.
+
+### Implementation Comments
+
+Provide comments explaining tricky, subtle, or complicated sections of code.
+
+```objectivec
+// GOOD:
+
+// Set the property to nil before invoking the completion handler to
+// avoid the risk of reentrancy leading to the callback being
+// invoked again.
+CompletionHandler handler = self.completionHandler;
+self.completionHandler = nil;
+handler();
+```
+
+When useful, also provide comments about implementation approaches that were
+considered or abandoned.
+
+End-of-line comments should be separated from the code by at least 2 spaces. If
+you have several comments on subsequent lines, it can often be more readable to
+line them up.
+
+```objectivec
+// GOOD:
+
+[self doSomethingWithALongName]; // Two spaces before the comment.
+[self doSomethingShort]; // More spacing to align the comment.
+```
+
+### Disambiguating Symbols
+
+Where needed to avoid ambiguity, use backticks or vertical bars to quote
+variable names and symbols in comments in preference to using quotation marks
+or naming the symbols inline.
+
+In Doxygen-style comments, prefer demarcating symbols with a monospace text
+command, such as `@c`.
+
+Demarcation helps provide clarity when a symbol is a common word that might make
+the sentence read like it was poorly constructed. A common example is the symbol
+`count`:
+
+```objectivec
+// GOOD:
+
+// Sometimes `count` will be less than zero.
+```
+
+or when quoting something which already contains quotes
+
+```objectivec
+// GOOD:
+
+// Remember to call `StringWithoutSpaces("foo bar baz")`
+```
+
+Backticks or vertical bars are not needed when a symbol is self-apparent.
+
+```objectivec
+// GOOD:
+
+// This class serves as a delegate to GTMDepthCharge.
+```
+
+Doxygen formatting is also suitable for identifying symbols.
+
+```objectivec
+// GOOD:
+
+/** @param maximum The highest value for @c count. */
+```
+
+### Object Ownership
+
+For objects not managed by ARC, make the pointer ownership model as explicit as
+possible when it falls outside the most common Objective-C usage idioms.
+
+#### Manual Reference Counting
+
+Instance variables for NSObject-derived objects are presumed to be retained; if
+they are not retained, they should be either commented as weak or declared with
+the `__weak` lifetime qualifier.
+
+An exception is in Mac software for instance variables labeled as `@IBOutlets`,
+which are presumed to not be retained.
+
+Where instance variables are pointers to Core Foundation, C++, and other
+non-Objective-C objects, they should always be declared with strong and weak
+comments 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.
+
+Examples of strong and weak declarations:
+
+```objectivec
+// GOOD:
+
+@interface MyDelegate : NSObject
+
+@property(nonatomic) NSString *doohickey;
+@property(nonatomic, weak) NSString *parent;
+
+@end
+
+
+@implementation MyDelegate {
+ IBOutlet NSButton *_okButton; // Normal NSControl; implicitly weak on Mac only
+
+ AnObjcObject *_doohickey; // My doohickey
+ MyObjcParent * __weak _parent; // To send messages back (owns this instance)
+
+ // non-NSObject pointers...
+ CWackyCPPClass *_wacky; // Strong, some cross-platform object
+ CFDictionaryRef *_dict; // Strong
+}
+@end
+```
+
+#### Automatic Reference Counting
+
+Object ownership and lifetime are explicit when using ARC, so no additional
+comments are required for automatically retained objects.
+
+## C Language Features
+
+### Macros
+
+Avoid macros, especially where `const` variables, enums, XCode snippets, or C
+functions may be used instead.
+
+Macros make the code you see different from the code the compiler sees. Modern C
+renders traditional uses of macros for constants and utility functions
+unnecessary. Macros should only be used when there is no other solution
+available.
+
+Where a macro is needed, use a unique name to avoid the risk of a symbol
+collision in the compilation unit. If practical, keep the scope limited by
+`#undefining` the macro after its use.
+
+Macro names should use `SHOUTY_SNAKE_CASE`—all uppercase letters with
+underscores between words. Function-like macros may use C function naming
+practices. Do not define macros that appear to be C or Objective-C keywords.
+
+```objectivec
+// GOOD:
+
+#define GTM_EXPERIMENTAL_BUILD ... // GOOD
+
+// Assert unless X > Y
+#define GTM_ASSERT_GT(X, Y) ... // GOOD, macro style.
+
+// Assert unless X > Y
+#define GTMAssertGreaterThan(X, Y) ... // GOOD, function style.
+```
+
+```objectivec
+// AVOID:
+
+#define kIsExperimentalBuild ... // AVOID
+
+#define unless(X) if(!(X)) // AVOID
+```
+
+Avoid macros that expand to unbalanced C or Objective-C constructs. Avoid macros
+that introduce scope, or may obscure the capturing of values in blocks.
+
+Avoid macros that generate class, property, or method definitions in
+headers to be used as public API. These only make the code hard to
+understand, and the language already has better ways of doing this.
+
+Avoid macros that generate method implementations, or that generate declarations
+of variables that are later used outside of the macro. Macros shouldn't make
+code hard to understand by hiding where and how a variable is declared.
+
+```objectivec
+// AVOID:
+
+#define ARRAY_ADDER(CLASS) \
+ -(void)add ## CLASS ## :(CLASS *)obj toArray:(NSMutableArray *)array
+
+ARRAY_ADDER(NSString) {
+ if (array.count > 5) { // AVOID -- where is 'array' defined?
+ ...
+ }
+}
+```
+
+Examples of acceptable macro use include assertion and debug logging macros
+that are conditionally compiled based on build settings—often, these are
+not compiled into release builds.
+
+### Nonstandard Extensions
+
+Nonstandard extensions to C/Objective-C may not be used unless otherwise
+specified.
+
+Compilers support various extensions that are not part of standard C. Examples
+include compound statement expressions (e.g. `foo = ({ int x; Bar(&x); x }))`
+and variable-length arrays.
+
+`__attribute__` is an approved exception, as it is used in Objective-C API
+specifications.
+
+The binary form of the conditional operator, `A ?: B`, is an approved exception.
+
+## Cocoa and Objective-C Features
+
+### Identify Designated Initializer
+
+Clearly identify your designated initializer.
+
+It is important for those who might be subclassing your class that the
+designated initializer be clearly identified. That way, they only need to
+override a single initializer (of potentially several) to guarantee the
+initializer of their subclass 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. Identify the designated initializer using comments or the
+`NS_DESIGNATED_INITIALIZER` macro. If you use `NS_DESIGNATED_INITIALIZER`, mark
+unsupported initializers with `NS_UNAVAILABLE`.
+
+### Override Designated Initializer
+
+When writing a subclass that requires an `init...` method, make sure you
+override the designated initializer of the superclass.
+
+If you fail to override the designated initializer of the superclass, your
+initializer may not be called in all cases, leading to subtle and very difficult
+to find bugs.
+
+### Overridden NSObject Method Placement
+
+Put overridden methods of NSObject at the top of an `@implementation`.
+
+This commonly applies to (but is not limited to) the `init...`, `copyWithZone:`,
+and `dealloc` methods. The `init...` methods should be grouped together,
+followed by other typical `NSObject` methods such as `description`, `isEqual:`,
+and `hash`.
+
+Convenience class factory methods for creating instances may precede the
+`NSObject` methods.
+
+### Initialization
+
+Don't initialize instance variables to `0` or `nil` in the `init` method; doing
+so is redundant.
+
+All instance variables for a newly allocated object are [initialized
+to](https://developer.apple.com/library/mac/documentation/General/Conceptual/CocoaEncyclopedia/ObjectAllocation/ObjectAllocation.html)
+`0` (except for isa), so don't clutter up the init method by re-initializing
+variables to `0` or `nil`.
+
+### Instance Variables In Headers Should Be @protected or @private
+
+Instance variables should typically be declared in implementation files or
+auto-synthesized by properties. When ivars are declared in a header file, they
+should be marked `@protected` or `@private`.
+
+```objectivec
+// GOOD:
+
+@interface MyClass : NSObject {
+ @protected
+ id _myInstanceVariable;
+}
+@end
+```
+
+### Avoid +new
+
+Do not invoke the `NSObject` class method `new`, nor override it in a subclass.
+Instead, use `alloc` and `init` methods to instantiate retained objects.
+
+Modern Objective-C code explicitly calls `alloc` and an `init` method to create
+and retain an object. As the `new` class method is rarely used, it makes
+reviewing code for correct memory management more difficult.
+
+### Keep the Public API Simple
+
+Keep your class simple; avoid "kitchen-sink" APIs. If a method doesn't need to
+be public, keep it out of the public interface.
+
+Unlike C++, Objective-C doesn't differentiate between public and private
+methods; any message may be sent to an object. 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.
+
+Since internal methods are not really private, it's easy to 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.
+
+### #import and #include
+
+`#import` Objective-C and Objective-C++ headers, and `#include` C/C++ headers.
+
+Choose between `#import` and `#include` based on the language of the header that
+you are including.
+
+
+When including a header that uses Objective-C or Objective-C++, use `#import`.
+When including a standard C or C++ header, use `#include`.
+The header should provide its own `#define` guard.
+
+### Order of Includes
+
+The standard order for header inclusion is the related header, operating system
+headers, language library headers, and finally groups of headers for other
+dependencies.
+
+The related header precedes others to ensure it has no hidden dependencies.
+For implementation files the related header is the header file.
+For test files the related header is the header containing the tested interface.
+
+A blank line may separate logically distinct groups of included headers.
+
+Import headers using their path relative to the project's source directory.
+
+```objectivec
+// GOOD:
+
+#import "ProjectX/BazViewController.h"
+
+#import
+
+#include
+#include
+
+#include "base/basictypes.h"
+#include "base/integral_types.h"
+#include "util/math/mathutil.h"
+
+#import "ProjectX/BazModel.h"
+#import "Shared/Util/Foo.h"
+```
+
+### Use Umbrella Headers for System Frameworks
+
+Import umbrella headers for system frameworks and system libraries rather than
+include individual files.
+
+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` or `#import` rather than `#include` for Objective-C frameworks.
+
+```objectivec
+// GOOD:
+
+@import UIKit; // GOOD.
+#import // GOOD.
+```
+
+```objectivec
+// AVOID:
+
+#import // AVOID.
+#import
+...
+```
+
+### Avoid Accessors During init and dealloc
+
+Instance subclasses may be in an inconsistent state during init and dealloc
+method execution, so code in those methods should avoid invoking accessors on
+self.
+
+Subclasses have not yet been initialized or have already deallocated when init
+and dealloc methods execute, making accessor methods on self potentially
+unreliable. Whenever practical, directly assign to and release ivars in those
+methods rather than rely on accessors.
+
+```objectivec
+// GOOD:
+
+- (instancetype)init {
+ self = [super init];
+ if (self) {
+ _bar = 23; // GOOD.
+ }
+ return self;
+}
+```
+
+```objectivec
+// AVOID:
+
+- (instancetype)init {
+ self = [super init];
+ if (self) {
+ self.bar = 23; // AVOID.
+ }
+ return self;
+}
+```
+
+```objectivec
+// GOOD:
+
+- (void)dealloc {
+ [_notifier removeObserver:self]; // GOOD.
+}
+```
+
+```objectivec
+// AVOID:
+
+- (void)dealloc {
+ [self removeNotifications]; // AVOID.
+}
+```
+
+### Setters copy NSStrings
+
+Setters taking an `NSString` should always copy the string it accepts. This is
+often also appropriate for collections like `NSArray` and `NSDictionary`.
+
+Never just retain the string, as it may be a `NSMutableString`. This avoids the
+caller changing it under you without your knowledge.
+
+Code receiving and holding collection objects should also consider that the
+passed collection may be mutable, and thus the collection could be more safely
+held as a copy or mutable copy of the original.
+
+```objectivec
+// GOOD:
+
+@property(nonatomic, copy) NSString *name;
+
+- (void)setZigfoos:(NSArray *)zigfoos {
+ // Ensure that we're holding an immutable collection.
+ _zigfoos = [zigfoos copy];
+}
+```
+
+### Use Lightweight Generics to Document Contained Types
+
+All projects compiling on Xcode 7 or newer versions should make use of the
+Objective-C lightweight generics notation to type contained objects.
+
+Every `NSArray`, `NSDictionary`, or `NSSet` reference should be declared using
+lightweight generics for improved type safety and to explicitly document usage.
+
+```objectivec
+// GOOD:
+
+@property(nonatomic, copy) NSArray *locations;
+@property(nonatomic, copy, readonly) NSSet *identifiers;
+
+NSMutableArray *mutableLocations = [otherObject.locations mutableCopy];
+```
+
+If the fully-annotated types become complex, consider using a typedef to
+preserve readability.
+
+```objectivec
+// GOOD:
+
+typedef NSSet *> TimeZoneMappingSet;
+TimeZoneMappingSet *timeZoneMappings = [TimeZoneMappingSet setWithObjects:...];
+```
+
+Use the most descriptive common superclass or protocol available. In the most
+generic case when nothing else is known, declare the collection to be explicitly
+heterogenous using id.
+
+```objectivec
+// GOOD:
+
+@property(nonatomic, copy) NSArray *unknowns;
+```
+
+### Avoid Throwing Exceptions
+
+Don't `@throw` Objective-C exceptions, but you should be prepared to catch them
+from third-party or OS calls.
+
+This follows the recommendation to use error objects for error delivery in
+[Apple's Introduction to Exception Programming Topics for
+Cocoa](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Exceptions/Exceptions.html).
+
+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.
+
+### `nil` Checks
+
+Use `nil` checks for logic flow only.
+
+Use `nil` pointer checks for logic flow of the application, not for preventing
+crashes when sending messages. Sending a message to `nil` [reliably
+returns](http://www.sealiesoftware.com/blog/archive/2012/2/29/objc_explain_return_value_of_message_to_nil.html)
+`nil` as a pointer, zero as an integer or floating-point value, structs
+initialized to `0`, and `_Complex` values equal to `{0, 0}`.
+
+Note that this applies to `nil` as a message target, not as a parameter value.
+Individual methods may or may not safely handle `nil` parameter values.
+
+Note too that this is distinct from checking C/C++ pointers and block 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 Pitfalls
+
+Be careful when converting general integral values to `BOOL`. Avoid comparing
+directly with `YES`.
+
+`BOOL` in OS X and in 32-bit iOS builds is defined as a signed `char`, so it may
+have values other than `YES` (`1`) and `NO` (`0`). Do not cast or convert
+general integral values directly to `BOOL`.
+
+Common mistakes include casting or converting an array's size, a pointer value,
+or the result of a bitwise logic operation to a `BOOL` that could, depending on
+the value of the last byte of the integer value, still result in a `NO` value.
+When converting a general integral value to a `BOOL` use ternary operators to
+return a `YES` or `NO` value.
+
+You can safely interchange and convert `BOOL`, `_Bool` and `bool` (see C++ Std
+4.7.4, 4.12 and C99 Std 6.3.1.2). Use `BOOL` in Objective C method signatures.
+
+Using logical operators (`&&`, `||` and `!`) with `BOOL` is also valid and will
+return values that can be safely converted to `BOOL` without the need for a
+ternary operator.
+
+```objectivec
+// AVOID:
+
+- (BOOL)isBold {
+ return [self fontTraits] & NSFontBoldTrait; // AVOID.
+}
+- (BOOL)isValid {
+ return [self stringValue]; // AVOID.
+}
+```
+
+```objectivec
+// GOOD:
+
+- (BOOL)isBold {
+ return ([self fontTraits] & NSFontBoldTrait) ? YES : NO;
+}
+- (BOOL)isValid {
+ return [self stringValue] != nil;
+}
+- (BOOL)isEnabled {
+ return [self isValid] && [self isBold];
+}
+```
+
+Also, don't directly compare `BOOL` variables directly with `YES`. Not only is
+it harder to read for those well-versed in C, but the first point above
+demonstrates that return values may not always be what you expect.
+
+```objectivec
+// AVOID:
+
+BOOL great = [foo isGreat];
+if (great == YES) { // AVOID.
+ // ...be great!
+}
+```
+
+```objectivec
+// GOOD:
+
+BOOL great = [foo isGreat];
+if (great) { // GOOD.
+ // ...be great!
+}
+```
+
+### Interfaces Without Instance Variables
+
+Omit the empty set of braces on interfaces that do not declare any instance
+variables.
+
+```objectivec
+// GOOD:
+
+@interface MyClass : NSObject
+// Does a lot of stuff.
+- (void)fooBarBam;
+@end
+```
+
+```objectivec
+// AVOID:
+
+@interface MyClass : NSObject {
+}
+// Does a lot of stuff.
+- (void)fooBarBam;
+@end
+```
+
+## Cocoa Patterns
+
+### Delegate Pattern
+
+Delegates, target objects, and block pointers should not be retained when doing
+so would create a retain cycle.
+
+To avoid causing a retain cycle, a delegate or target pointer should be released
+as soon as it is clear there will no longer be a need to message the object.
+
+If there is no clear time at which the delegate or target pointer is no longer
+needed, the pointer should only be retained weakly.
+
+Block pointers cannot be retained weakly. To avoid causing retain cycles in the
+client code, block pointers should be used for callbacks only where they can be
+explicitly released after they have been called or once they are no longer
+needed. Otherwise, callbacks should be done via weak delegate or target
+pointers.
+
+## Objective-C++
+
+### Style Matches the Language
+
+Within an Objective-C++ source file, follow the style for the language of the
+function or method you're implementing. 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.
+
+For code in an `@implementation` block, use the Objective-C naming rules. For
+code in a method of a C++ class, use the C++ naming rules.
+
+For code in an Objective-C++ file outside of a class implementation, be
+consistent within the file.
+
+```objectivec++
+// GOOD:
+
+// 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 stringWithFormat:@"%d", _instanceVar];
+ NSLog(@"%@", tempString);
+}
+
+@end
+
+// The platform-specific implementation of the C++ class, using
+// C++ naming.
+int CrossPlatformAPI::DoSomethingPlatformSpecific() {
+ NSString* temp_string = [NSString stringWithFormat:@"%d", an_instance_var_];
+ NSLog(@"%@", temp_string);
+ return [temp_string intValue];
+}
+```
+
+Projects may opt to use an 80 column line length limit for consistency with
+Google's C++ style guide.
+
+## Objective-C Style Exceptions
+
+### Indicating style exceptions
+
+Lines of code that are not expected to adhere to these style recommendations
+require `// NOLINT` at the end of the line or `// NOLINTNEXTLINE` at the end of
+the previous line. Sometimes it is required that parts of Objective-C code must
+ignore these style recommendations (for example code may be machine generated or
+code constructs are such that its not possible to style correctly).
+
+A `// NOLINT` comment on that line or `// NOLINTNEXTLINE` on the previous line
+can be used to indicate to the reader that code is intentionally ignoring style
+guidelines. In addition these annotations can also be picked up by automated
+tools such as linters and handle code correctly. Note that there is a single
+space between `//` and `NOLINT*`.
diff --git a/objcguide.xml b/objcguide.xml
deleted file mode 100644
index 1fb404b36..000000000
--- a/objcguide.xml
+++ /dev/null
@@ -1,1884 +0,0 @@
-
-
-
-
-
-
-Revision 2.59
-
-
-
-
-
-
- Mike Pinkerton
- Greg Miller
- Dave MacLachlan
-
-
-
-
-
-
-
-
- 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.
-
-
-
- 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:
-
-
-
-
-
-
- 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
-
- Programming with Objective-C
- .
-
-
-
-
-
-
-
- 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
-
-
-
- #import <Foundation/Foundation.h>
-
- // A sample class demonstrating good Objective-C style. All interfaces,
- // categories, and protocols (read: all non-trivial 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
-
- // Returns an autoreleased instance of Foo. See -initWithBar: for details
- // about |bar|.
- + (instancetype)fooWithBar:(NSString *)bar;
-
- // Designated initializer. |bar| is a thing that represents a thing that
- // does a thing.
- - (instancetype)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
-
-
-
- An example source file, demonstrating 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
.
-
-
-
- #import "Foo.h"
-
-
- @implementation Foo {
- NSString *_bar;
- NSString *_foo;
- }
-
- + (instancetype)fooWithBar:(NSString *)bar {
- return [[[self alloc] initWithBar:bar] autorelease];
- }
-
- // Must always override super's designated initializer.
- - (instancetype)init {
- return [self initWithBar:nil];
- }
-
- - (instancetype)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
-
-
-
- Blank lines before and after @interface
,
- @implementation
, and @end
are optional. If your
- @interface
declares instance variables, a blank
- line should come after the closing brace (}
).
-
-
- 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.
-
-
-
-
-
-
-
-
- Use only spaces, and indent 2 spaces at a time.
-
-
-
- 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.
-
-
-
-
-
-
- The maximum line length for Objective-C and Objective-C++ files is 100
- columns. Projects may opt to use an 80 column limit for consistency with
- the C++ style guide.
-
-
-
- You can make violations easier to spot by enabling Preferences >
- Text Editing > Page guide at column: 100 in Xcode.
-
-
-
-
-
-
- One space should be used between the -
or +
- and the return type, and no spacing in the parameter list except between
- parameters.
-
-
-
- Methods should look like this:
-
-
- - (void)doSomethingWithString:(NSString *)theString {
- ...
- }
-
-
- 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 colon before the parameter.
-
-
- - (void)doSomethingWith:(GTMFoo *)theFoo
- rect:(NSRect)theRect
- interval:(float)theInterval {
- ...
- }
-
-
- When the first keyword is shorter than the others, indent the later
- lines by at least four spaces, maintaining colon alignment:
-
-
- - (void)short:(GTMFoo *)theFoo
- longKeyword:(NSRect)theRect
- evenLongerKeyword:(float)theInterval
- error:(NSError **)theError {
- ...
- }
-
-
-
-
-
-
- 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.
-
-
-
- Invocations should have all arguments on one line:
-
-
- [myObject doFooWith:arg1 name:arg2 error:arg3];
-
-
- or have one argument per line, with colons aligned:
-
-
- [myObject doFooWith:arg1
- name:arg2
- error:arg3];
-
-
- Don't use any of these styles:
-
-
- [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];
-
-
-
- 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:
-
-
- [myObj short:arg1
- longKeyword:arg2
- evenLongerKeyword:arg3
- error:arg4];
-
-
- Invocations containing inlined blocks may have
- their segments left-aligned at a four space indent.
-
-
-
-
-
-
- The @public
and @private
access modifiers
- should be indented by 1 space.
-
-
-
- This is similar to public
, private
, and
- protected
in C++.
-
-
- @interface MyClass : NSObject {
- @public
- ...
- @private
- ...
- }
- @end
-
-
-
-
-
-
- Format exceptions with each @
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, format them as follows. However, see
- Avoid Throwing Exceptions for
- reasons why you should not be using exceptions.
-
-
- @try {
- foo();
- }
- @catch (NSException *ex) {
- bar(ex);
- }
- @finally {
- baz();
- }
-
-
-
-
-
-
- There should not be a space between the type identifier and the name
- of the protocol encased in angle brackets.
-
-
-
- This applies to class declarations, instance variables, and method
- declarations. For example:
-
-
- @interface MyProtocoledClass : NSObject<NSWindowDelegate> {
- @private
- id<MyFancyDelegate> _delegate;
- }
- - (void)setDelegate:(id<MyFancyDelegate>)aDelegate;
- @end
-
-
-
-
-
-
- Code inside blocks should be indented four spaces.
-
-
-
- There are several appropriate style rules, depending on how long the
- block is:
-
-
- - If the block can fit on one line, no wrapping is necessary.
- -
- If it has to wrap, the closing brace should line up with the first
- character of the line on which the block is declared.
-
- - Code within the block should be indented four spaces.
- -
- If the block is large, e.g. more than 20 lines, it is recommended to
- move it out-of-line into a local variable.
-
- -
- If the block takes no parameters, there are no spaces between the
- characters
^{
. If the block takes parameters, there is no
- space between the ^(
characters, but there is one space
- between the ) {
characters.
-
- -
- Invocations containing inlined blocks may have their segments
- left-aligned at a four-space indent. This helps when invocations
- contain multiple inlined blocks.
-
- -
- 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.
-
-
-
- // 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];
-
- // An example with multiple inlined blocks in one invocation.
- [myObject doSomethingWith:arg1
- firstBlock:^(Foo *a) {
- // ...
- }
- secondBlock:^(Bar *b) {
- // ...
- }];
-
-
-
-
-
-
- For projects using Xcode 4.4 or later and clang, the use of container
- (array and dictionary) literals is encouraged. If split across multiple
- lines, the contents should be indented two spaces.
-
-
-
- If the collection fits on one line, put a single space after the opening
- and before the closing brackets.
-
-
- NSArray* array = @[ [foo description], @"Another String", [bar description] ];
-
- NSDictionary* dict = @{ NSForegroundColorAttributeName : [NSColor redColor] };
-
-
- Not:
-
-
- NSArray* array = @[[foo description], [bar description]];
-
- NSDictionary* dict = @{NSForegroundColorAttributeName: [NSColor redColor]};
-
-
-
- If the collection spans more than a single line, place the opening
- bracket on the same line as the declaration, indent the body by two
- spaces, and place the closing bracket on a new line that is indented to
- the same level as the opening bracket.
-
-
- NSArray* array = @[
- @"This",
- @"is",
- @"an",
- @"array"
- ];
-
- NSDictionary* dictionary = @{
- NSFontAttributeName : [NSFont fontWithName:@"Helvetica-Bold" size:12],
- NSForegroundColorAttributeName : fontColor
- };
-
-
-
- For dictionary literals, there should be one space before the colon and
- at least one space after it (to optionally align the values).
-
-
- NSDictionary* option1 = @{
- NSFontAttributeName : [NSFont fontWithName:@"Helvetica-Bold" size:12],
- NSForegroundColorAttributeName : fontColor
- };
-
- NSDictionary* option2 = @{
- NSFontAttributeName : [NSFont fontWithName:@"Arial" size:12],
- NSForegroundColorAttributeName : fontColor
- };
-
-
- The following are all incorrect:
-
-
- // There should be a space before the colon.
- NSDictionary* wrong = @{
- AKey: @"b",
- BLongerKey: @"c",
- };
-
- // The items should each be on a new line, or the entire expression
- // should fit on one line.
- NSDictionary* alsoWrong= @{ AKey : @"a",
- BLongerKey : @"b" };
-
- // There should be no variable space before the colon, only after.
- NSDictionary* stillWrong = @{
- AKey : @"b",
- BLongerKey : @"c",
- };
-
-
-
-
-
-
-
-
- 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
- initialisms
- 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.
-
-
-
-
- File names should reflect the name of the class implementation that
- they contain—including case. Follow the convention that your
-
- project
- uses.
-
-
-
- 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
-
-
-
-
-
-
- Within a source file, Objective-C++ follows the style of the
- function/method you're implementing.
-
-
-
- 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.
-
-
- // 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 stringWithFormat:@"%d", _instanceVar];
- NSLog(@"%@", tempString);
- }
- @end
-
- // The platform-specific implementation of the C++ class, using
- // C++ naming.
- int CrossPlatformAPI::DoSomethingPlatformSpecific() {
- NSString* temp_string = [NSString stringWithFormat:@"%d", an_instance_var_];
- NSLog(@"%@", temp_string);
- return [temp_string intValue];
- }
-
-
-
-
-
-
- Class names (along with category and protocol names) should start as
- uppercase and use mixed case to delimit words.
-
-
-
- When designing code to be shared across multiple applications,
- prefixes are acceptable and recommended (e.g. GTMSendMessage
).
- Prefixes are also recommended for classes of large applications that
- depend on external libraries.
-
-
-
-
-
-
-
- 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.
-
-
-
- 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.
-
-
- There should be a single space between the class name and the opening
- parenthesis of the category.
-
-
- // Extending a framework class:
- @interface NSString (GTMStringParsingAdditions)
- - (NSString *)gtm_foobarString;
- @end
-
- // Making your methods and properties private:
- @interface FoobarViewController ()
- @property(nonatomic, retain) NSView *dongleView;
- - (void)performLayout;
- @end
-
-
-
-
-
-
- Method names should start as lowercase and then use mixed case.
- Each named parameter should also start as lowercase.
-
-
-
- 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:
-
- - (id)getDelegate; // AVOID
-
-
- - (id)delegate; // GOOD
-
-
-
- This is for Objective-C methods only. C++ method names and functions
- continue to follow the rules set in the C++ style guide.
-
-
-
-
-
-
- Variables names start with a lowercase and use mixed case to delimit
- words. Instance variables have leading underscores. For example:
- myLocalVariable, _myInstanceVariable.
-
-
-
-
- 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:
-
-
- int w;
- int nerr;
- int nCompConns;
- tix = [[NSMutableArray alloc] init];
- obj = [someObject object];
- p = [network port];
-
-
- int numErrors;
- int numCompletedConnections;
- tickets = [[NSMutableArray alloc] init];
- userInfo = [someObject object];
- port = [network port];
-
-
-
-
-
- Instance variables are mixed case and should be prefixed with an
- underscore e.g. _usernameTextField. 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.
-
-
-
-
-
- Constant names (#defines, enums, const local variables, etc.) should
- start with a lowercase k and then use mixed case to
- delimit words. For example:
-
-
- const int kNumberOfFiles = 12;
- NSString *const kUserKey = @"kUserKey";
- enum DisplayTinge {
- kDisplayTingeGreen = 1,
- kDisplayTingeBlue = 2
- };
-
-
- Because Objective-C does not provide namespacing, constants with global
- scope should have an appropriate prefix to minimize the chance of name
- collision, typically like kClassNameFoo.
-
-
-
-
-
-
-
-
-
-
- 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.
-
-
-
-
- A file may optionally start with a description of its contents.
-
-
-
-
- Every file should contain the following items, in order:
-
- - license boilerplate if neccessary. Choose the appropriate
- boilerplate for the license used by the project (e.g.
- Apache 2.0, BSD, LGPL, GPL).
- - a basic description of the contents of the file if necessary.
-
-
-
- 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.
-
-
-
-
-
-
- Every interface, category, and protocol declaration should have an
- accompanying comment describing its purpose and how it fits into the
- larger picture.
-
-
-
- // A delegate for NSApplication to handle notifications about app
- // launch and shutdown. Owned by the main app controller.
- @interface MyAppDelegate : NSObject {
- ...
- }
- @end
-
-
- 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.
-
-
-
-
-
-
- Use vertical bars to quote variable names and symbols in comments rather
- than quotes or naming the symbol inline.
-
-
-
- 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":
-
-
- // Sometimes we need |count| to be less than zero.
-
-
- or when quoting something which already contains quotes
-
-
- // Remember to call |StringWithoutSpaces("foo bar baz")|
-
-
-
-
-
-
- Make the pointer ownership model as explicit as possible when it falls
- outside the most common Objective-C usage idioms.
-
-
-
-
- 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 __weak lifetime qualifier when applicable.
- Similarly, declared properties must specify an assign 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.
-
-
- Where instance variables are pointers to Core Foundation, C++, and
- other non-Objective-C objects, they should always be declared with
- strong
and weak
comments 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.
-
-
- Examples of strong and weak declarations:
-
- @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...
- CWackyCPPClass *_wacky; // Strong, some cross-platform object
- CFDictionaryRef *_dict; // Strong
- }
- @property(strong, nonatomic) NSString *doohickey;
- @property(weak, nonatomic) NSString *parent;
- @end
-
-
-
-
-
- Object ownership and lifetime are explicit when using ARC, so no
- additional comments are required.
-
-
-
-
-
-
-
-
-
-
-
- Instance variables should typically be declared in implementation files
- or auto-synthesized by properties. When ivars are declared in a header
- file, they should be marked @private
.
-
-
-
- @interface MyClass : NSObject {
- @private
- id _myInstanceVariable;
- }
- @end
-
-
-
-
-
-
- Comment and clearly identify your designated initializer.
-
-
-
- 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.
-
-
-
-
-
-
- When writing a subclass that requires an 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.
-
-
-
-
-
-
- It is strongly recommended and typical practice to place overridden
- methods of NSObject
at the top of an
- @implementation
.
-
-
-
- This commonly applies (but is not limited) to the init...
,
- copyWithZone:
, and dealloc
methods.
- init...
methods should be grouped together, followed by
- other NSObject
methods.
-
-
- Convenience class methods for creating instances may precede the
- NSObject
methods.
-
-
-
-
-
-
- Don't initialize variables to 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
.
-
-
-
-
-
-
- Do not invoke the NSObject
class method new
,
- nor override it in a subclass. Instead, use alloc
and
- init
methods to instantiate retained objects.
-
-
-
- Modern Objective-C code explicitly calls alloc
and an
- init
method to create and retain an object. As the
- new
class method is rarely used, it makes reviewing code
- for correct memory management more difficult.
-
-
-
-
-
-
- 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.
-
-
-
- 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.
-
-
- #import "GTMFoo.h"
-
- @interface GTMFoo (PrivateDelegateHandling)
- - (NSString *)doSomethingWithDelegate; // Declare private method
- @end
-
- @implementation GTMFoo (PrivateDelegateHandling)
- ...
- - (NSString *)doSomethingWithDelegate {
- // Implement this method
- }
- ...
- @end
-
-
- If you are using Objective-C 2.0, you should instead declare your
- private category using a class
- extension, for example:
-
-
- @interface GMFoo () { ... }
-
-
- 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
).
-
-
-
-
-
-
- #import
Objective-C/Objective-C++ headers, and
- #include
C/C++ headers.
-
-
-
- Choose between #import
and #include
based
- on the language of the header that you are including.
-
-
- - When including a header that uses Objective-C or Objective-C++,
- use
#import
.
- - When including a standard C or C++ header, use
-
#include
. The header should provide its own #define
- guard.
-
-
- Some Objective-C headers lack #define
guards, and expect
- to be included only by #import
. As Objective-C headers
- may only be included in Objective-C source files and other Objective-C
- headers, using #import
across the board is appropriate.
-
-
- 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
- #import
in standard C or C++, such files will be
- included by #include
in those cases. Using
- #include
for them in Objective-C source files as well
- means that these headers will always be included with the same
- semantics.
-
-
- This rule helps avoid inadvertent errors in cross-platform
- projects. A Mac developer introducing a new C or C++ header might
- forget to add #define
guards, which would not cause
- problems on the Mac if the new header were included with
- #import
, but would break builds on other platforms
- where #include
is used. Being consistent by using
- #include
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.
-
-
- #import <Cocoa/Cocoa.h>
- #include <CoreFoundation/CoreFoundation.h>
- #import "GTMFoo.h"
- #include "base/basictypes.h"
-
-
-
-
-
-
- Include root frameworks over individual files.
-
-
-
- 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
for Objective-C frameworks.
-
-
- #import <Foundation/Foundation.h> // good
-
-
- #import <Foundation/NSArray.h> // avoid
- #import <Foundation/NSString.h>
- ...
-
-
-
-
-
-
- When creating new temporary objects, 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.:
-
-
- // AVOID (unless you have a compelling performance reason)
- MyController* controller = [[MyController alloc] init];
- // ... code here that might return ...
- [controller release];
-
-
- // BETTER
- MyController* controller = [[[MyController alloc] init] autorelease];
-
-
-
-
-
-
- Assignment of objects follows the 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.
-
-
- - (void)setFoo:(GMFoo *)aFoo {
- [_foo autorelease]; // Won't dealloc if |_foo| == |aFoo|
- _foo = [aFoo retain];
- }
-
-
-
-
-
-
- Instance subclasses may be in an inconsistent state during
- init
and dealloc
method execution, so code in
- those methods should avoid invoking accessors.
-
-
-
- Subclasses have not yet been initialized or have already deallocated
- when init
and dealloc
methods execute, making
- accessor methods potentially unreliable. Whenever practical, directly
- assign to and release ivars in those methods rather than rely on
- accessors.
-
-
- - (instancetype)init {
- self = [super init];
- if (self) {
- _bar = [[NSMutableString alloc] init]; // good
- }
- return self;
- }
-
- - (void)dealloc {
- [_bar release]; // good
- [super dealloc];
- }
-
-
- - (instancetype)init {
- self = [super init];
- if (self) {
- self.bar = [NSMutableString string]; // avoid
- }
- return self;
- }
-
- - (void)dealloc {
- self.bar = nil; // avoid
- [super dealloc];
- }
-
-
-
-
-
-
- dealloc
should process instance variables in the same order
- the @interface
declares them, so it is easier for a reviewer
- to verify.
-
-
-
- A code reviewer checking a new or revised dealloc
- implementation needs to make sure that every retained instance
- variable gets released.
-
-
- To simplify reviewing dealloc
, order the code so that
- the retained instance variables get released in the same order that
- they are declared in the @interface
. If
- dealloc
invokes other methods that release instance
- variables, add comments describing what instance variables those
- methods handle.
-
-
-
-
-
-
- Setters taking an 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
.
-
-
- - (void)setFoo:(NSString *)aFoo {
- [_foo autorelease];
- _foo = [aFoo copy];
- }
-
-
-
-
-
-
- Don't @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.
-
-
-
-
-
-
-
- Use nil
checks for logic flow only.
-
-
-
- Use nil
pointer checks for logic flow of the application,
- not for preventing crashes when sending messages. With current compilers
- (
- as of LLVM 3.0/Xcode 4.2), sending a message to nil
- reliably returns nil as a pointer, zero as an integer or floating-point
- value, structs initialized to 0, and _Complex
values equal
- to {0, 0}.
-
-
- Note that this applies to nil
as a message target, not as
- a parameter value. Individual methods may or may not safely handle
- nil
parameter values.
-
-
- Note too that this is distinct from checking C/C++ pointers and block
- 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.
-
-
-
-
-
-
- Be careful when converting general integral values to BOOL
.
- Avoid comparing directly with YES
.
-
-
-
- BOOL
is defined as a signed char in Objective-C which means
- that it can have values other than YES
(1) and
- NO
(0). Do not cast or convert general integral values
- directly to BOOL
. Common mistakes include casting or
- converting an array's size, a pointer value, or the result of a bitwise
- logic operation to a BOOL
which, depending on the value of
- the last byte of the integral result, could still result in a
- NO
value. When converting a general integral value to a
- BOOL
use ternery operators to return a YES
or
- NO
value.
-
-
- You can safely interchange and convert BOOL
,
- _Bool
and bool
(see C++ Std 4.7.4, 4.12 and
- C99 Std 6.3.1.2). You cannot safely interchange BOOL
and
- Boolean
so treat Booleans
as a general
- integral value as discussed above. Only use BOOL
in
- Objective C method signatures.
-
-
- Using logical operators (&&
, ||
and
- !
) with BOOL
is also valid and will return
- values that can be safely converted to BOOL
without the
- need for a ternery operator.
-
-
- - (BOOL)isBold {
- return [self fontTraits] & NSFontBoldTrait;
- }
- - (BOOL)isValid {
- return [self stringValue];
- }
-
-
- - (BOOL)isBold {
- return ([self fontTraits] & NSFontBoldTrait) ? YES : NO;
- }
- - (BOOL)isValid {
- return [self stringValue] != nil;
- }
- - (BOOL)isEnabled {
- return [self isValid] && [self isBold];
- }
-
-
- Also, don't directly compare BOOL
variables directly
- with YES
. 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.
-
-
- BOOL great = [foo isGreat];
- if (great == YES)
- // ...be great!
-
-
- BOOL great = [foo isGreat];
- if (great)
- // ...be great!
-
-
-
-
-
-
-
- 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 @property
.
-
-
-
-
- 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 @property
and the opening parenthesis
- should be omitted, as seen in the examples.
-
-
-
- @interface MyClass : NSObject
- @property(copy, nonatomic) NSString *name;
- @end
-
- @implementation MyClass
- // No code required for auto-synthesis, else use:
- // @synthesize name = _name;
- @end
-
-
-
-
- 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
- @implementation
block in a class definition. They are
- indented at the same level as the @interface
or
- @implementation
statements that they are enclosed in.
-
-
- @interface MyClass : NSObject {
- @private
- NSString *_name;
- }
- @property(copy, nonatomic) NSString *name;
- @end
-
- @implementation MyClass
- @synthesize name = _name;
-
- - (instancetype)init {
- ...
- }
- @end
-
-
-
-
- NSString properties should always be declared with the
- copy
attribute.
-
-
- This logically follows from the requirement that setters for
- NSStrings always must use copy
instead of
- retain
.
-
-
-
-
- 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 nonatomic
unless you require atomicity.
-
-
-
-
- Dot notation is idiomatic style for Objective-C 2.0. It may be used
- when doing simple operations to get and set a @property
- of an object, but should not be used to invoke other object behavior.
-
-
- NSString *oldName = myObject.name;
- myObject.name = @"Alice";
-
-
- NSArray *array = [[NSArray arrayWithObject:@"hello"] retain];
-
- NSUInteger numberOfItems = array.count; // not a property
- array.release; // not a property
-
-
-
-
-
-
-
- Omit the empty set of braces on interfaces that do not declare any
- instance variables.
-
-
-
- @interface MyClass : NSObject
- // Does a lot of stuff
- - (void)fooBarBam;
- @end
-
-
- @interface MyClass : NSObject {
- }
- // Does a lot of stuff
- - (void)fooBarBam;
- @end
-
-
-
-
-
-
-
- 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.
-
-
-
-
- // 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
-
-
-
- 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).
-
-
-
-
-
-
-
- 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.
-
-
- Classes that require ARC should include a preprocessor directive to
- prevent compilation using manual reference counting.
-
-
- Ownership qualifiers like __unsafe_unretained
and
- __weak
should precede variable names. Specifying
- __strong
for variables is not required since it is
- the default. Properties, on the other hand, should always specify the
- strong
keyword rather than relying on the compiler default.
-
-
- Files that are compiled using ARC need to have preprocessor directives
- to prevent compilation without ARC. See the code snippet below for
- details.
-
-
-
-
- Example of an implementation file enforcing ARC style. Note that
- declaring instance variables in the @implementation is permitted when
- using ARC.
-
- #if !defined(__has_feature) || !__has_feature(objc_arc)
- #error "This file requires ARC support."
- #endif
-
- #import "Foo.h"
-
- @implementation Foo {
- Bar* __weak _bar;
- Baz* __unsafe_unretained _baz;
- }
- // ...
- @end
-
-
-
-
-
-
-
-
- For projects that use Xcode 4.4 or later with clang, the use of
- NSNumber literals
- is allowed. Note however that this will limit the portability of your
- code to other toolchains.
-
-
-
-
- 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.
-
- NSNumber *fortyTwo = @42;
- NSNumber *piOverTwo = @(M_PI / 2);
- enum {
- kMyEnum = 2;
- };
- NSNumber *myEnum = @(kMyEnum);
-
-
-
-
-
-
-
-
-
-
-
- Delegate objects should not be retained when doing so would create
- a retain cycle.
-
-
-
- A class that implements the delegate pattern should typically:
-
- -
- Have an instance variable named _delegate to reference
- the delegate.
-
- -
- Thus, the accessor methods should be named
delegate
- and setDelegate:
.
-
- -
- The _delegate object should be weak if the class
- is typically retained by its delegate, such that a strong delegate
- would create a retain cycle.
-
-
-
-
-
-
-
-
- Separate the model from the view. Separate the controller from the
- view and the model. Use @protocol
s for callback APIs.
-
-
-
-
- -
- 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.)
-
- -
- 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.
-
- -
- Define callback APIs with
@protocol
, using
- @optional
if not all the methods are required.
-
-
-
-
-
-
-
-
-
-
-
-
- Trailing underscores were once preferred for instance variable names.
-
-
-
- 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.
-
-
-
-
-
-
-
-
-
-Revision 2.59
-
-
-
-
-
-Mike Pinkerton
-Greg Miller
-Dave MacLachlan
-
-