Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
O

objc-zen-book

> 编程语言
Open source

Zen and the Art of the Objective-C Craftsmanship

2.6K stars0 likes3 views
WebsiteGitHub

About

Zen and the Art of the Objective-C Craftsmanship

Zen and the Art of the Objective-C Craftsmanship

  • Preface
    • Swift
    • For the Community
    • Authors
  • Conditionals
    • Yoda conditions
    • nil and BOOL checks
    • Golden Path
    • Complex Conditions
    • Ternary Operator
    • Error handling
  • Case Statements
    • Enumerated Types
  • Naming
    • General conventions
    • Constants
    • Methods
    • Literals
  • Class
    • Class name
    • Initializer and dealloc
      • Designated and Secondary Initializers
        • Designated Initializer
        • Secondary Initializer
          • References
      • instancetype
        • Reference
      • Initialization Patterns
        • Class cluster
        • Singleton
    • Properties
      • Init and Dealloc
      • Dot-Notation
      • Property Declaration
        • Private Properties
      • Mutable Object
      • Lazy Loading
    • Methods
      • Parameter Assert
      • Private methods
    • Equality
  • Categories
  • Protocols
  • NSNotification
  • Beautifying the code
    • Spacing
    • Line Breaks
    • Brackets
  • Code Organization
    • Exploit Code Block
    • Pragma
      • Pragma Mark
    • Explicit warnings and errors
    • Docstrings
    • Comments
      • Header Documentation
  • Inter-Object Communication
    • Blocks
      • Under the Hood
      • Retain cycles on self
    • Delegate and DataSource
      • Inheritance
      • Multiple Delegation
  • Aspect Oriented Programming
  • References
    • Other Objective-C Style Guides

Preface

We started writing this book on November 2013. The initial goal was to provide guidelines to write the most clean Objective-C code possible: there are too many guidelines out there and all of them are debatable. We didn't aim introducing hard rules but, instead, a way for writing code to be more uniform as possible across different developers. With time the scope moved to explain how to design and architecture good code.

The idea underneath is that the code should not only compile, instead it should "validate". Good code has several characteristics: should be concise, self-explanatory, well organized, well documented, well named, well designed and stand the test of time. The main goals behind the curtain are that clarity always wins over performance and a rationale for a choice should always be provided. Some topics discussed here are general and independent from the language even if everything is tied up to Objective-C.

Swift

On June 6th, 2014 Apple announced the new programming language to be used for iOS and Mac development in future: Swift. This new language is a radical departure from Objective-C and, of course, has caused a change in our plan for writing this book. It boiled down to the decision of releasing the current status of this essay without continuing our journey in unfolding the topics we originally planned to include. Objective-C is not going anywhere but at the same time continuing to write a book on a language that will not receive the same attention as it used to, is not a wise move.

For the Community

We have released this book for free and for the community because we hope to provide value to the reader, if each one of you can learn at least one best practice we have reached our goal.

We have done our best to polish this text and make it pleasant to the reader but we may have made typos, mistakes or left any part incomplete. We strongly encourage you to give us feedback and suggest improvements, so please get in touch with us if have any. We particularly appreciate pull requests.

Authors

Luca Bernardi

  • http://lucabernardi.com
  • @luka_bernardi
  • http://github.com/lukabernardi

Alberto De Bortoli

  • http://albertodebortoli.com
  • @albertodebo
  • http://github.com/albertodebortoli

Conditionals

Conditional bodies should always use braces even when a conditional body could be written without braces (e.g., it is one line only) to prevent errors. These errors include adding a second line and expecting it to be part of the if-statement. Another, even more dangerous defect, may happen where the line "inside" the if-statement is commented out, and the next line unwittingly becomes part of the if-statement.

Preferred:

objective-c
if (!error) {
    return success;
}

Not preferred:

objective-c
if (!error)
    return success;

or

objective-c
if (!error) return success;

In February 2014 the well-know goto fail was found in the Apple's SSL/TLS implementation. The bug was due to a repeated goto statement after an if condition, wrapping the if branch in parentheses would have prevented the issue.

The code extract:

objective-c
static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams,
                                 uint8_t *signature, UInt16 signatureLen)
{
  OSStatus        err;
  ...

  if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
    goto fail;
  if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
    goto fail;
    goto fail;
  if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
    goto fail;
  ...

fail:
  SSLFreeBuffer(&signedHashes);
  SSLFreeBuffer(&hashCtx);
  return err;
}

Easy to spot, there are 2 goto fail; lines one after the other without parentheses. We definitely don't want to risk creating bugs like the one above right?

In addition, this style is more consistent with all other conditionals, and therefore more easily scannable.

Yoda conditions

Always avoid Yoda conditions. A Yoda condition is when comparing a constant to a variable instead of the other way around. It's like saying "if blue is the sky" or "if tall is the man" instead of "if the sky is blue" or "if the man is tall".

Preferred:

objective-c
if ([myValue isEqual:@42]) { ...

Not preferred:

objective-c
if ([@42 isEqual:myValue]) { ...

nil and BOOL checks

On a similar note of the Yoda conditions, also the nil check has been at the centre of debates. Some notous libraries out there use to check for an object to be or not to be nil as so:

objective-c
if (nil == myValue) { ...

One could argue that this is amiss or similar to a Yoda condition as nil is kind of a constant. The reason why sometimes programmers use this approach to prevent error that are difficult to debug. Consider the following code:

objective-c
if (myValue == nil) { ...

If a typo occurs and the programmer actually types:

objective-c
if (myValue = nil) { ...

it would be a valid assignment, indeed hard to debug if you are an experienced programmer (and therefore probably with some kind of visual impairment). That could never occur putting nil as argument on the left as it is nor assignable. There is also to be said that if the programmer uses this approach, he or she is perfectly aware of the underlying motivation and therefore the whole thing decades as it would be better to just double check what just typed.

More on this, to avoid all this fuss the approach that leave no space to doubt is to use the exclamation mark. Since nil resolves to NO it is unnecessary to compare it in conditions. Also, never compare something directly to YES, because YES is defined to 1 and a BOOL can be up to 8 bits as it is a char underneath.

Preferred:

objective-c
if (someObject) { ...
if (![someObject boolValue]) { ...
if (!someObject) { ...

Not Preferred:

objective-c
if (someObject == YES) { ... // Wrong
if (myRawValue == YES) { ... // Never do this.
if ([someObject boolValue] == NO) { ...

This allows also for more consistency across files and greater visual clarity.

Golden Path

When coding with conditionals, the left hand margin of the code should be the "golden" or "happy" path. That is, don't nest if statements. Multiple return statements are OK. This will avoid the growth of cyclomatic complexity and make the code easier to read because the important part of your method is not nested inside a branch but you have a visual clue of what is the most relevant code.

Preferred:

objective-c
- (void)someMethod {
  if (![someOther boolValue]) {
      return;
  }

  //Do something important
}

Not preferred:

objective-c
- (void)someMethod {
  if ([someOther boolValue]) {
    //Do something important
  }
}

Complex Conditions

When you have complex condition in the if clause you should always extract them and assign to a BOOL variable to make more clear the logic and the meaning of every single conditions.

objective-c
BOOL nameContainsSwift  = [sessionName containsString:@"Swift"];
BOOL isCurrentYear      = [sessionDateCompontents year] == 2014;
BOOL isSwiftSession     = nameContainsSwift && isCurrentYear;

if (isSwiftSession) {
    // Do something very cool
}

Ternary Operator

The Ternary operator, ? , should only be used when it increases clarity or code neatness. A single condition is usually all that should be evaluated. Evaluating multiple conditions is usually more understandable as an if statement, or refactored into instance variables.

Preferred:

objective-c
result = a > b ? x : y;

Not preferred:

objective-c
result = a > b ? x = c > d ? c : d : y;

When the second argument of the ternary operator (the if branch) returns the same object that was checked for existence in the condition, the following syntax is neat:

Preferred:

objective-c
result = object ? : [self createObject];

Not preferred:

objective-c
result = object ? object : [self createObject];

Error handling

When methods return an error parameter by reference, check the returned value, not the error variable.

Preferred:

objective-c
NSError *error = nil;
if (![self trySomethingWithError:&error]) {
    // Handle Error
}

Moreover, some of Apple's APIs write garbage values to the error parameter (if non-NULL) in successful cases, so checking the error can cause false negatives (and subsequently crash).

Case Statements

Braces are not required for case statements, unless enforced by the complier.
When a case contains more than one line, braces should be added.

objective-c
switch (condition) {
    case 1:
        // ...
        break;
    case 2: {
        // ...
        // Multi-line example using braces
        break;
       }
    case 3:
        // ...
        break;
    default: 
        // ...
        break;
}

There are times when the same code can be used for multiple cases, and a fall-through should be used. A fall-through is the removal of the 'break' statement for a case thus allowing the flow of execution to pass to the next case value.

objective-c
switch (condition) {
    case 1:
    case 2:
        // code executed for values 1 and 2
        break;
    def

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Ruby

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言