|
CodingStyle
Coding Style GuidelinesLanguageName your variables, classes, methods, functions and all other things in American English. Comments should likewise be in English, but your own local English is fine (as long as it's readable to anyone fluent in any dialect of English). Variable namesInstance and local variables should generally be named in camelCase, with a lowercase initial letter, and no underscores. No form of Hungarian notation is to be used, ever. Type and class namesUse struct or enum when allowed: struct sockaddr saddr; struct FSForkIOParam pb; But not when this is discouraged (as with some Cocoa structures): NSRect rect; //NOT struct _NSRect Classes should be named in CamelCase, with an uppercase initial letter, and no underscores. Name your classes so that it's obvious what they belong to and what they're for. Classes should have a two letter prefix. This may be your initials if you prefer, or you may use FR (for FadingRed). (e.g. FRCamelCaseObject ) Methods should be arranged as follows: + (Foo *)classMethods; + (id)classMethodsThatCreateObjects; //e.g. new or newWithZone - (id)init; - (id)initWithExtraArgument:(id)extraArgument andOtherExtraArgument:(id)otherExtraArgument; - (void)dealloc; // Other instance methods Don't use 'int' unless there are no qualifiers on it. All three of these declarations are correct: int x; // no qualifiers unsigned y; // qualifier 'unsigned' short z; // qualifier 'short' Selector namesAlways include return type, even if it's id. All parameter names are assumed to be inputs, unless noted otherwise. You might consider using the 'in' or 'out' keyword if it needs to be explicitly disambiguated. - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)column row:(int)row; - (BOOL)scanUpToString:(NSString *)inString intoString:(NSString **)outString; Variable DeclarationsAlways initialize variables at declaration time or immediately afterwards. Never use a variable's value without initializing it first. Message line breakingEncouraged for long messages: // Animate the icon
animationTimer = [[NSTimer scheduledTimerWithTimeInterval:ANIMATION_DELAY
target:self
selector:@selector(animateIcon:)
userInfo:nil
repeats:YES] retain];(Note how the colons line up vertically in a monospaced font.) The correct number of tabs and spaces to line up the colons can be inserted automatically by Xcode, by using the Re-Indent command in the Format menu. Line breaking is generally encouraged for all sorts of long expressions, provided it does not reduce readability. Consider: if (some_long_condition &&
some_other_long_condition ||
some_completely_different_long_condition)over: if (some_long_condition && some_other_long_condition || some_completely_different_long_condition) Braces and Whitespace- (BOOL)textAndButtonsWindowDidEnd:(NSWindow *)window returnCode:(AITextAndButtonsReturnCode)returnCode userInfo:(id)userInfo {
if (returnCode == AITextAndButtonsDefaultReturn) {
[self gotDefaultReturn]; // To explain the current line of code
} else if (returnCode == AITextAndButtonsOtherReturn) {
// A multi-line comment should be formatted like this and
// explain the code below. Write your code so it is understandable
// without comments... and comment it! This helps you and helps
// future programmers work with your code.
[self gotOtherReturn];
} else {
// A longer, single line comment to explain the next line of code
[self displayError];
}
}Braces for method/function definition go on the same line as the definition. The last brace of an if-else chain should be on its own line, but all other braces in the chain (opening braces and closing braces) should be on the same line as the statement. Always use tabs to indent. Never spaces. Ever. Indent your instance variables, too. Always use spaces around operators: 2 + 2, not 2+2 x && y, not x&&y x << 256 not x<<256 Put a space between a keyword and the opening parenthesis: if (a) // not: if(a) But not between a function name and the opening parenthesis: printf("%s", "Hello world!
");
// not: printf ("%s", "Hello world!
");Don't pad the inside of the parentheses with spaces: if (a && b) // not: if ( a && b ) Don't use parentheses around the argument to return (making it look like a function call): return 0; // not: return(0); But it's OK for parenthesized expressions: return ((x * y) ? 42 : [array objectAtIndex:fallback]); Leave all blank lines (those with no visible characters) empty (not containing any characters). This means that a blank line should not contain any tabs or spaces. LabelsLabels should always be on a line by themselves, and should be 1 indent to the left of the statement they apply to: switch (answer) {
case 42:
printf("Found the answer! (%i)
", answer);
}Note that in a switch, all statements are indented two levels to allow for the case labels. Comments// C99 single-line comments are allowed. /* * Multi-line comments at the beginning of a file should be used * whenever a comment spans multiple lines, like this one. Be * sure the stars line up in a nice column, and that the end wing * is on its own line. Also make sure you use a space after the * column of stars and that your lines are about the same length. */ // Anywhere else in the file, multiline comments // should be made on separate lines by commenting // out each line. Again the lines should be about // The same length. Single-line comments should not be placed on the same line as long statements: // Area is pi * r-squared area = 3.141592653589793238462643383279502884197169399375105820974944592307816406286 * r * r; rather than: area = 3.141592653589793238462643383279502884197169399375105820974944592307816406286 * r * r; // pi * r-squared But for short statements, you may place it at the end: area = 3.14 * r * r; // pi * r-squared Multi-line comments should always come before the statement. Multiple return statementsReturn statements should be used at the end of methods unless there is a very good reason to do otherwise. Example of how to avoid using a return statement in the middle of a method: - (NSString *)whosYourDaddy:(NSString *)inChild
{
NSString *returnString = nil;
if (inChild) {
returnString = @"Alan Kay";
}
return returnString;
}Use of +newDo not use +new. Use +alloc/-init. Ternary operator (foo ? bar : baz)Allowed, and encouraged where readability is increased. Make it three lines, with appropriate indenting, if foo, bar, and/or baz are long. Always use parenthesis. Index variablesAlways unsigned unless necessary. Never use index variables for NSArrays; use NSEnumerator to iterate on those. (Only keep an index variable if you need to replace elements of an NSMutableArray.) Numeric constants and NULL vs. nilAlways supply a fraction and an integer in any floating-point constant: 0.0, not 0. or .0. Specify type constants only if strictly necessary. Use nil for Cocoa types, and NULL elsewhere: - (char *) UTF8String
{
if (UTF8String == NULL) {
UTF8String = malloc([self length]);
}
if (UTF8String != NULL) {
strcpy(UTF8String, "I am the Walrus");
}
return UTF8String;
}The above is for example purposes; whenever testing against NULL/nil, use simple truth-testing (and the ! operator when appropriate): void *buf = NULL;
size_t size = 0U, increment = getpagesize();
do {
buf = realloc(buf, size);
if (!buf) {
NSLog(@"Could not allocate %zu bytes", size);
} else {
size += increment;
}
} while (buf);Otherwise, always use constants whenever possible; for example:
CreditsThis document is based on Adium's CodingStyle, with modifications for the FadingRed coding style. |
