From a7dd19342d893d685223721f331bc63dd5a2b60e Mon Sep 17 00:00:00 2001 From: pinkerton Date: Wed, 10 Sep 2008 19:31:02 +0000 Subject: [PATCH] Add section on properties from dmaclach, remove some tabs. --- objcguide.xml | 452 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 317 insertions(+), 135 deletions(-) diff --git a/objcguide.xml b/objcguide.xml index 7b3ee69..9599ca2 100644 --- a/objcguide.xml +++ b/objcguide.xml @@ -5,13 +5,13 @@
-
- Mike Pinkerton
- Greg Miller
- Dave MacLachlan -
+
+ Mike Pinkerton
+ Greg Miller
+ Dave MacLachlan +
- + @@ -34,31 +34,40 @@ -

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.

+

+ 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.

+

+ 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: -

+

+ 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: +

@@ -80,8 +89,11 @@

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). + 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.

@@ -91,124 +103,126 @@

Note that this guide is not an Objective-C tutorial. We assume that the reader is familiar with the language. If you are new to Objective-C or - need a refresher, please read The - Objective-C Programming Language. + need a refresher, please read + + The Objective-C Programming Language + .

- +

They say an example is worth a thousand words so let's start off with an example that should give you a feel for the style, spacing, naming, etc.

- An example header file, demonstrating the correct commenting and spacing + An example header file, demonstrating the correct commenting and spacing for an @interface declaration

-
-  //  GTMFoo.h
-  //  FooProject
-  //
-  //  Created by Greg Miller on 6/13/08.
-  //  Copyright 2008 Google, Inc. All rights reserved.
-  //
-
-  #import <Foundation/Foundation.h>
-
-  // A sample class demonstrating good Objective-C style. All interfaces,
-  // categories, and protocols (read: all top-level declarations in a header)
-  // MUST be commented. Comments must also be adjacent to the object they're
-  // documenting.
-  //
-  // (no blank line between this comment and the interface)
-  @interface GTMFoo : NSObject {
-   @private
-    NSString *foo_;
-    NSString *bar_;
-  }
-
-  // Returns an autoreleased instance of GMFoo. See -initWithString: for details
-  // about the argument.
-  + (id)fooWithString:(NSString *)string;
-
-  // Designated initializer. |string| will be copied and assigned to |foo_|.
-  - (id)initWithString:(NSString *)string;
-
-  // Gets and sets the string for |foo_|.
-  - (NSString *)foo;
-  - (void)setFoo:(NSString *)newFoo;
-
-  // Does some work on |blah| and returns YES if the work was completed
-  // successfuly, and NO otherwise.
-  - (BOOL)doWorkWithString:(NSString *)blah;
-
-  @end
-
- + + // GTMFoo.h + // FooProject + // + // Created by Greg Miller on 6/13/08. + // Copyright 2008 Google, Inc. All rights reserved. + // + + #import <Foundation/Foundation.h> + + // A sample class demonstrating good Objective-C style. All interfaces, + // categories, and protocols (read: all top-level declarations in a header) + // MUST be commented. Comments must also be adjacent to the object they're + // documenting. + // + // (no blank line between this comment and the interface) + @interface GTMFoo : NSObject { + @private + NSString *foo_; + NSString *bar_; + } + + // Returns an autoreleased instance of GMFoo. See -initWithString: for details + // about the argument. + + (id)fooWithString:(NSString *)string; + + // Designated initializer. |string| will be copied and assigned to |foo_|. + - (id)initWithString:(NSString *)string; + + // Gets and sets the string for |foo_|. + - (NSString *)foo; + - (void)setFoo:(NSString *)newFoo; + + // Does some work on |blah| and returns YES if the work was completed + // successfuly, and NO otherwise. + - (BOOL)doWorkWithString:(NSString *)blah; + + @end + +

- An example source file, demonstating the correct commenting and spacing + An example source file, demonstating the correct commenting and spacing for the @implementation of an interface. It also includes the reference implementations for important methods like getters and setters, init, and dealloc.

- -
-  //
-  //  GTMFoo.m
-  //  FooProject
-  //
-  //  Created by Greg Miller on 6/13/08.
-  //  Copyright 2008 Google, Inc. All rights reserved.
-  //
-
-  #import "GTMFoo.h"
-
-
-  @implementation GTMFoo
-
-  + (id)fooWithString:(NSString *)string {
-    return [[[self alloc] initWithString:string] autorelease];
-  }
-
-  // Must always override super's designated initializer.
-  - (id)init {
-    return [self initWithString:nil];
-  }
-
-  - (id)initWithString:(NSString *)string {
-    if ((self = [super init])) {
-      foo_ = [string copy];
-      bar_ = [[NSString alloc] initWithFormat:@"hi %d", 3];
+  
+  
+    //
+    //  GTMFoo.m
+    //  FooProject
+    //
+    //  Created by Greg Miller on 6/13/08.
+    //  Copyright 2008 Google, Inc. All rights reserved.
+    //
+    
+    #import "GTMFoo.h"
+    
+    
+    @implementation GTMFoo
+    
+    + (id)fooWithString:(NSString *)string {
+      return [[[self alloc] initWithString:string] autorelease];
     }
-    return self;   
-  }
-
-  - (void)dealloc {
-    [foo_ release];
-    [bar_ release];
-    [super dealloc];
-  }
-
-  - (NSString *)foo {
-    return foo_;
-  }
-
-  - (void)setFoo:(NSString *)newFoo {
-    [foo_ autorelease];
-    foo_ = [newFoo copy];   
-  }
-
-  - (BOOL)doWorkWithString:(NSString *)blah {
-    // ...
-    return NO;
-  }
-
-  @end
-
+ + // Must always override super's designated initializer. + - (id)init { + return [self initWithString:nil]; + } + + - (id)initWithString:(NSString *)string { + if ((self = [super init])) { + foo_ = [string copy]; + bar_ = [[NSString alloc] initWithFormat:@"hi %d", 3]; + } + return self; + } + + - (void)dealloc { + [foo_ release]; + [bar_ release]; + [super dealloc]; + } + + - (NSString *)foo { + return foo_; + } + + - (void)setFoo:(NSString *)newFoo { + [foo_ autorelease]; + foo_ = [newFoo copy]; + } + + - (BOOL)doWorkWithString:(NSString *)blah { + // ... + return NO; + } + + @end +
@@ -828,11 +842,11 @@

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 + 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.

@@ -1123,9 +1137,177 @@ - + + + + Properties in general are allowed with the following caveat: properties + are an Objective-C 2.0 feature which will limit your code to running + on the iPhone and MacOS X 10.5 (Leopard) and higher. Dot notation to + access properties is not allowed. + + + +

+ A property's associated instance variable's name must conform to the + trailing _ requirement. The property's name should be the same as its + associated instance variable without the trailing _. +

+

+ Use the @synthesize directive to rename the property correctly. +

+ + + @interface MyClass : NSObject { + @private + NSString *name_; + } + @property(copy, nonatomic) NSString *name; + @end + + @implementation MyClass + @synthesize name = name_; + @end + +
+ +

+ A property's declaration must come immediately after the instance + variable block of a class interface. A property's definition 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_; + - (id)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. +

+
+ +

+ CFTypes should always have the @dynamic implementation + directive. +

+

+ Since CFTypes can't have the retain property + attribute, the developer must handle retaining and releasing the + value themselves. In the rare case that you do actually want + assignment it is better to make that completely clear by actually + implementing the setter and getter and commenting why that is the + case. +

+
+ +

+ Use implementation directives for all properties even if they are + @dynamic by default. +

+

+ Even though @dynamic is default, explicitly list it out + with all of the other property implementation directives making it + clear how every property in a class is handled at a single glance. +

+ + @interface MyClass : NSObject + @property(readonly) NSString *name; + @end + + @implementation MyClass + . + . + . + - (NSString*)name { + return @"foo"; + } + @end + + + @interface MyClass : NSObject + @property(readonly) NSString *name; + @end + + @implementation MyClass + @dynamic name; + . + . + . + - (NSString*)name { + return @"foo"; + } + @end + +
+ +

+ 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. +

+
+ +

+ We do not allow the use of dot notation to access properties for + the following reasons: +

+
    +
  1. + Dot notation is purely syntactic sugar for standard method calls, + whose readability gains are debatable. It just gives you another + way to make method calls. +
  2. +
  3. + It obscures the type that you are dereferencing. When one sees: + [foo setBar:1] it is immediately clear that you are + working with an Objective-C object. When one sees + foo.bar = 1 it is not clear if foo is an object, or + a struct/union/C++ class. +
  4. +
  5. + It allows you to do method calls that look like getters. + + NSString *upperCase = @"foo".uppercaseString; + + which is not only confusing, but difficult to spot in a code review. +
  6. +
  7. + It hides method calls. + + bar.value += 10; + + is actually two separate method calls (one to set and one to get) + and if your properties are not simple you may find a lot of work + being done in a hidden manner. +
  8. +
+
+ +
+