Giter Club home page Giter Club logo

objective-c-style-guide's Introduction

[DEPRECATED]

NYTimes Objective-C Style Guide is deprecated. No more development will be taking place. Thanks for all your support!

NYTimes Objective-C Style Guide

This style guide outlines the coding conventions of the iOS teams at The New York Times. We welcome your feedback in issues and pull requests. Also, we’re hiring.

Thanks to all of our contributors.

Introduction

Here are some of the documents from Apple that informed the style guide. If something isn’t mentioned here, it’s probably covered in great detail in one of these:

This style guide conforms to IETF's RFC 2119. In particular, code which goes against the RECOMMENDED/SHOULD style is allowed, but should be carefully considered.

Table of Contents

Dot Notation Syntax

Dot notation is RECOMMENDED over bracket notation for getting and setting properties.

For example:

view.backgroundColor = UIColor.orangeColor;
UIApplication.sharedApplication.delegate;

Not:

[view setBackgroundColor:[UIColor orangeColor]];
[UIApplication sharedApplication].delegate;

Spacing

  • Indentation MUST use 4 spaces. Never indent with tabs. Be sure to set this preference in Xcode.
  • Method braces and other braces (if/else/switch/while etc.) MUST open on the same line as the statement. Braces MUST close on a new line.

For example:

if (user.isHappy) {
    // Do something
}
else {
    // Do something else
}
  • There SHOULD be exactly one blank line between methods to aid in visual clarity and organization.
  • Whitespace within methods MAY separate functionality, though this inclination often indicates an opportunity to split the method into several, smaller methods. In methods with long or verbose names, a single line of whitespace MAY be used to provide visual separation before the method’s body.
  • @synthesize and @dynamic MUST each be declared on new lines in the implementation.

Conditionals

Conditional bodies MUST 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 can happen where the line “inside” the if-statement is commented out, and the next line unwittingly becomes part of the if-statement. In addition, this style is more consistent with all other conditionals, and therefore more easily scannable.

For example:

if (!error) {
    return success;
}

Not:

if (!error)
    return success;

or

if (!error) return success;

Ternary Operator

The intent of the ternary operator, ? , is to increase clarity or code neatness. The ternary SHOULD only evaluate a single condition per expression. Evaluating multiple conditions is usually more understandable as an if statement or refactored into named variables.

For example:

result = a > b ? x : y;

Not:

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

Error Handling

When methods return an error parameter by reference, code MUST switch on the returned value and MUST NOT switch on the error variable.

For example:

NSError *error;
if (![self trySomethingWithError:&error]) {
    // Handle Error
}

Not:

NSError *error;
[self trySomethingWithError:&error];
if (error) {
    // Handle Error
}

Some of Apple’s APIs write garbage values to the error parameter (if non-NULL) in successful cases, so switching on the error can cause false negatives (and subsequently crash).

Methods

  • In method signatures, there SHOULD be a space after the scope (- or + symbol). There SHOULD be a space between the method segments.

For example:

- (void)setExampleText:(NSString *)text image:(UIImage *)image;
  • Methods exceeding 80 characters SHOULD be represented like a form with a new line after each argument

For example:

- (void)setExampleText:(NSString *)text 
                 image:(UIImage *)image 
                 color:(UIColor *)color 
       alternativeText:(NSString *)altText;

Variables

Variables SHOULD be named descriptively, with the variable’s name clearly communicating what the variable is and pertinent information a programmer needs to use that value properly.

For example:

  • NSString *title: It is reasonable to assume a “title” is a string.
  • NSString *titleHTML: This indicates a title that may contain HTML which needs parsing for display. “HTML” is needed for a programmer to use this variable effectively.
  • NSAttributedString *titleAttributedString: A title, already formatted for display. AttributedString hints that this value is not just a vanilla title, and adding it could be a reasonable choice depending on context.
  • NSDate *now: No further clarification is needed.
  • NSDate *lastModifiedDate: Simply lastModified can be ambiguous; depending on context, one could reasonably assume it is one of a few different types.
  • NSURL *URL vs. NSString *URLString: In situations when a value can reasonably be represented by different classes, it is often useful to disambiguate in the variable’s name.
  • NSString *releaseDateString: Another example where a value could be represented by another class, and the name can help disambiguate.

Single letter variable names are NOT RECOMMENDED, except as simple counter variables in loops.

Asterisks indicating a type is a pointer MUST be “attached to” the variable name. For example, NSString *text not NSString* text or NSString * text, except in the case of constants (NSString * const NYTConstantString).

Property definitions SHOULD be used in place of naked instance variables whenever possible. Direct instance variable access SHOULD be avoided except in initializer methods (init, initWithCoder:, etc…), dealloc methods and within custom setters and getters. For more information, see Apple’s docs on using accessor methods in initializer methods and dealloc.

For example:

@interface NYTSection : NSObject

@property (nonatomic) NSString *headline;

@end

Not:

@interface NYTSection : NSObject {
    NSString *headline;
}

Variable Qualifiers

When it comes to the variable qualifiers introduced with ARC, the qualifier (__strong, __weak, __unsafe_unretained, __autoreleasing) SHOULD be placed between the asterisks and the variable name, e.g., NSString * __weak text.

Naming

Apple naming conventions SHOULD be adhered to wherever possible, especially those related to memory management rules (NARC).

Long, descriptive method and variable names are good.

For example:

UIButton *settingsButton;

Not

UIButton *setBut;

A three letter prefix (e.g., NYT) MUST be used for class names and constants, however MAY be omitted for Core Data entity names. Constants MUST be camel-case with all words capitalized and prefixed by the related class name for clarity. A two letter prefix (e.g., NS) is reserved for use by Apple.

For example:

static const NSTimeInterval NYTArticleViewControllerNavigationFadeAnimationDuration = 0.3;

Not:

static const NSTimeInterval fadetime = 1.7;

Properties and local variables MUST be camel-case with the leading word being lowercase.

Instance variables MUST be camel-case with the leading word being lowercase, and MUST be prefixed with an underscore. This is consistent with instance variables synthesized automatically by LLVM. If LLVM can synthesize the variable automatically, then let it.

For example:

@synthesize descriptiveVariableName = _descriptiveVariableName;

Not:

id varnm;

Categories

Categories are RECOMMENDED to concisely segment functionality and should be named to describe that functionality.

For example:

@interface UIViewController (NYTMediaPlaying)
@interface NSString (NSStringEncodingDetection)

Not:

@interface NYTAdvertisement (private)
@interface NSString (NYTAdditions)

Methods and properties added in categories MUST be named with an app- or organization-specific prefix. This avoids unintentionally overriding an existing method, and it reduces the chance of two categories from different libraries adding a method of the same name. (The Objective-C runtime doesn’t specify which method will be called in the latter case, which can lead to unintended effects.)

For example:

@interface NSArray (NYTAccessors)
- (id)nyt_objectOrNilAtIndex:(NSUInteger)index;
@end

Not:

@interface NSArray (NYTAccessors)
- (id)objectOrNilAtIndex:(NSUInteger)index;
@end

Comments

When they are needed, comments SHOULD be used to explain why a particular piece of code does something. Any comments that are used MUST be kept up-to-date or deleted.

Block comments are NOT RECOMMENDED, as code should be as self-documenting as possible, with only the need for intermittent, few-line explanations. This does not apply to those comments used to generate documentation.

init and dealloc

dealloc methods SHOULD be placed at the top of the implementation, directly after the @synthesize and @dynamic statements. init methods SHOULD be placed directly below the dealloc methods of any class.

init methods should be structured like this:

- (instancetype)init {
    self = [super init]; // or call the designated initializer
    if (self) {
        // Custom initialization
    }
    return self;
}

Literals

NSString, NSDictionary, NSArray, and NSNumber literals SHOULD be used whenever creating immutable instances of those objects. Pay special care that nil values not be passed into NSArray and NSDictionary literals, as this will cause a crash.

For example:

NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"];
NSDictionary *productManagers = @{@"iPhone": @"Kate", @"iPad": @"Kamal", @"Mobile Web": @"Bill"};
NSNumber *shouldUseLiterals = @YES;
NSNumber *buildingZIPCode = @10018;

Not:

NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil];
NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil];
NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES];
NSNumber *buildingZIPCode = [NSNumber numberWithInteger:10018];

CGRect Functions

When accessing the x, y, width, or height of a CGRect, code MUST use the CGGeometry functions instead of direct struct member access. From Apple's CGGeometry reference:

All functions described in this reference that take CGRect data structures as inputs implicitly standardize those rectangles before calculating their results. For this reason, your applications should avoid directly reading and writing the data stored in the CGRect data structure. Instead, use the functions described here to manipulate rectangles and to retrieve their characteristics.

For example:

CGRect frame = self.view.frame;

CGFloat x = CGRectGetMinX(frame);
CGFloat y = CGRectGetMinY(frame);
CGFloat width = CGRectGetWidth(frame);
CGFloat height = CGRectGetHeight(frame);

Not:

CGRect frame = self.view.frame;

CGFloat x = frame.origin.x;
CGFloat y = frame.origin.y;
CGFloat width = frame.size.width;
CGFloat height = frame.size.height;

Constants

Constants are RECOMMENDED over in-line string literals or numbers, as they allow for easy reproduction of commonly used variables and can be quickly changed without the need for find and replace. Constants MUST be declared as static constants. Constants MAY be declared as #define when explicitly being used as a macro.

For example:

static NSString * const NYTAboutViewControllerCompanyName = @"The New York Times Company";

static const CGFloat NYTImageThumbnailHeight = 50.0;

Not:

#define CompanyName @"The New York Times Company"

#define thumbnailHeight 2

Enumerated Types

When using enums, the new fixed underlying type specification MUST be used; it provides stronger type checking and code completion. The SDK includes a macro to facilitate and encourage use of fixed underlying types: NS_ENUM().

Example:

typedef NS_ENUM(NSInteger, NYTAdRequestState) {
    NYTAdRequestStateInactive,
    NYTAdRequestStateLoading
};

Bitmasks

When working with bitmasks, the NS_OPTIONS macro MUST be used.

Example:

typedef NS_OPTIONS(NSUInteger, NYTAdCategory) {
    NYTAdCategoryAutos      = 1 << 0,
    NYTAdCategoryJobs       = 1 << 1,
    NYTAdCategoryRealState  = 1 << 2,
    NYTAdCategoryTechnology = 1 << 3
};

Private Properties

Private properties SHALL be declared in class extensions (anonymous categories) in the implementation file of a class.

For example:

@interface NYTAdvertisement ()

@property (nonatomic, strong) GADBannerView *googleAdView;
@property (nonatomic, strong) ADBannerView *iAdView;
@property (nonatomic, strong) UIWebView *adXWebView;

@end

Image Naming

Image names should be named consistently to preserve organization and developer sanity. Images SHOULD be named as one camel case string with a description of their purpose, followed by the un-prefixed name of the class or property they are customizing (if there is one), followed by a further description of color and/or placement, and finally their state.

For example:

  • RefreshBarButtonItem / RefreshBarButtonItem@2x and RefreshBarButtonItemSelected / RefreshBarButtonItemSelected@2x
  • ArticleNavigationBarWhite / ArticleNavigationBarWhite@2x and ArticleNavigationBarBlackSelected / ArticleNavigationBarBlackSelected@2x.

Images that are used for a similar purpose SHOULD be grouped in respective groups in an Images folder or Asset Catalog.

Booleans

Values MUST NOT be compared directly to YES, because YES is defined as 1, and a BOOL in Objective-C is a CHAR type that is 8 bits long (so a value of 11111110 will return NO if compared to YES).

For an object pointer:

if (!someObject) {
}

if (someObject == nil) {
}

For a BOOL value:

if (isAwesome)
if (!someNumber.boolValue)
if (someNumber.boolValue == NO)

Not:

if (isAwesome == YES) // Never do this.

If the name of a BOOL property is expressed as an adjective, the property’s name MAY omit the is prefix but should specify the conventional name for the getter.

For example:

@property (assign, getter=isEditable) BOOL editable;

Text and example taken from the Cocoa Naming Guidelines.

Singletons

Singleton objects SHOULD use a thread-safe pattern for creating their shared instance.

+ (instancetype)sharedInstance {
    static id sharedInstance = nil;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[[self class] alloc] init];
    });

    return sharedInstance;
}

This will prevent possible and sometimes frequent crashes.

Imports

If there is more than one import statement, statements MUST be grouped together. Groups MAY be commented.

Note: For modules use the @import syntax.

// Frameworks
@import QuartzCore;

// Models
#import "NYTUser.h"

// Views
#import "NYTButton.h"
#import "NYTUserView.h"

Protocols

In a delegate or data source protocol, the first parameter to each method SHOULD be the object sending the message.

This helps disambiguate in cases when an object is the delegate for multiple similarly-typed objects, and it helps clarify intent to readers of a class implementing these delegate methods.

For example:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;

Not:

- (void)didSelectTableRowAtIndexPath:(NSIndexPath *)indexPath;

Xcode project

The physical files SHOULD be kept in sync with the Xcode project files in order to avoid file sprawl. Any Xcode groups created SHOULD be reflected by folders in the filesystem. Code SHOULD be grouped not only by type, but also by feature for greater clarity.

Target Build Setting “Treat Warnings as Errors” SHOULD be enabled. Enable as many additional warnings as possible. If you need to ignore a specific warning, use Clang’s pragma feature.

Other Objective-C Style Guides

If ours doesn’t fit your tastes, have a look at some other style guides:

objective-c-style-guide's People

Contributors

ayanonagon avatar bcapps avatar brow avatar cdzombak avatar dkhamsing avatar dtellenbach avatar ericguirbal avatar fernandomatal avatar ishida avatar iwill avatar jacobvanorder avatar jawwad avatar loganmoseley avatar marlonandrade avatar mbbischoff avatar minsone avatar murdocdv avatar pacocardenal avatar paulbruneau avatar pburkart avatar peteog avatar phelps avatar raimon49 avatar readmecritic avatar twigz avatar veronique avatar victorteokw avatar vincentsit avatar xjshi avatar yorkepb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

objective-c-style-guide's Issues

More In-depth Explanations Where Possible

There are a few sections where we discussed motivations behind style choices in-person on our team and simply didn't explain, but there are also some that we cut when releasing publicly because they were too conversational in tone or not well-enough explained. The CGGemoetry functions section has a relevant quite that provides ample explanation for our reasoning, which that would serve us well in some other sections.

Dot notation, spacing, and some other sections are light on the reasoning even though we have considered each choice carefully. Some other sections are small stylistic choices that are pretty binary, but those need little explanation except preference.

Using "!" is not more clear than "== NO"

While I'm not a zealot about convincing others to move away from using ! in conditionals, I wouldn't ever give up my use of == NO. Not only are inverted conditions typically harder to mentally process, using ! in fact often reduces visual clarity. Typically, this is the result of a lack of whitespace with something like if (![object boolValue]) { a critically important part of the condition is jumbled up with the delineation elements of the syntax. This gets worse as the complexity of your if condition increases (admittedly this is often a clarity problem in it's own rite). if (!([obj bool1] && ![obj bool2]) { -- quick, what is the expected result?

Truthfully, the primary reason I stopped using ! (after vehemently arguing with a co-worker that he was silly for suggesting I avoid it) is because I caused myself a world of hurt once. During what seemed like a straight forward refactor, I managed to accidentally remove a !, we didn't even catch it during code review -- it was just so easy to miss. This happened to be one of those insidious bugs that ultimately took hours to track down, and a fraction of a second to correct.

Don't like == NO? Fine, don't use it -- but don't punish the defensive coders that would like to, especially not with an empty statement like "increases visual clarity".

Include prefix in category names and category method names on classes that aren't yours

I generally follow this rule: In a category on a class you don't own, prefix the name of the category as you would a class (in caps) in both the file name and the actual name. Prefix that category's method names with that prefix in lowercase, followed by an underscore. For example UIFont+NYTAdditions.h, UIFont (NYTAdditions), + (UIFont *)nyt_titleFont.

What is the best practice for exposing protected methods to subclasses?

For example UIGestureRecognizerSubclass.h uses a category in a new file, However this breaks the private properties rule, since it is not extending a class:

Named categories (such as NYTPrivate or private) should never be used unless extending another class.

Is there a better way to expose protected methods?

Ivars should be directly accessed in init'ers

Right now the guide simply says to use direct ivar access in dealloc. You should also directly access ivars in init* methods. More generally, you shouldn't really be invoking any method inside init* or dealloc methods. Other methods (including accessors that may be overridden) may expecting the object to be in a fully constructed state. When you're inside one of these methods, that is not the case.

Always use self.property except in initializer and dealloc methods

The style guide states that instance variables should always be accessed using self. if properties are being used. Apple recommends this as well but with an exception: except in initializer and dealloc methods.

This is due to the fact that during the time the object is being initialised (and, when applicable, dealloc'd), the object itself is considered to not be completely 'set up' with all of its properties publicly available for use and modification; the init and dealloc methods therefore respect this and as a result avoid any special behavior in the mutation and access of these properties that may assume a completely initialised state of the object.

I've seen this recommendation in a few places but I think the latest one in video form is at (and from) around the 6-minute mark of "Migrating to Modern Objective-C" from WWDC 2012.

Just thought I'd point this out as yet another geeky nitpick to a great style guide. :)

Statics and name prefixing

In your document a lot of variable names with the storage specifier static have prefixed names.

I understand the idea of prefixing for non-static consts, because during the linking phase the linker dies with obscure error messages. And if the names don't collide you still don't know which file is that topMargin coming from.

But what is the point of prefixing static variables? They can't be used outside of the file. The files shouldn't be long enough to need prefixing. It's easier and more clear to write topMargin instead of NYTBestViewControllerSidePanelTopMargin if we already have the NYTBestViewControllerSidePanelView.m opened.

Is there more rationale on this?

Automated style checker

Do you have any automated style checker on your CI-server? I've searched for tools like that and the only thing I've found is https://github.com/Cue/ocstyle, but it has hard-coded rules in python language. And seems not to be developing any more. More tools could be found here, but the most of them are designed to apply convention to code, not to check the style.

pragma marks and file structure

Hi,

I'm pretty sure you're using pragma marks a lot.

I'm curious what's your best practise to structure code then.

Here's an example from us (@nxtbgthng):

We usually structure our implementation files like so like so (let's call this one Class.m):

/* copy right comment if necessary */

#import <Framework/Framework.h>

#import "OtherHeader.h"
#import "OtherHeaderInSemanticalGroup.h"

#import "NextHeader.h"

#import "Class.h" // we import the implementation files header last


// place for consts and defines if you can't avoid them


@interface Class () <SecretNotVisibleFromHeaderProtocol>
@property (readonly) NSString *text;
@end


@implementation Class

#pragma mark Class Methods

+ (void)load;
{
}

#pragma mark Lifecycle

- (id)init;
{
    ....
}

- (void)dealloc;
{
    ....
}


#pragma mark Accessors

@synthesize text = _text; // readonly properties don't come with an ivar by default
- (NSString *)text
{
    if (!_text) {
        _text = @"text";
    }
    return _text;
}


#pragma mark SecretNotVisibleFromHeaderProtocol

- (void)methodDefinedInTheProtocol;
{
}


#pragma mark UIResponder

- (void)methodOverridenFromUIResponder;
{
}


#pragma mark Private Helper

- (CGRect)rectFromStuff:(id)stuff;
{
}

@end


#pragma mark -
#pragma mark Stuff private to this class

// Put private implementation blocks and C functions here.
// They need to be declared on top of the file though and might make things a little more messy

So key points are:

  • use pragma marks to group methods
  • when subclassing or implementing a protocol group the methods that do so under the name of the super class or protocol
  • always leave two empty lines above a pragma mark (we found them to be more visible that way)
  • use a Lifecycle section to group all init and dealloc
  • use a Class Methods section to group all static methods
  • use a Accessors section to group all custom getters and setters
  • keep @synthesize/@dynamic close to the getter/setter

Thanks for sharing your style guide. It's pretty close to how we do it which is a good sign for both of us ;)

-ullrich

Name symbols to end in the class or primitive type they represent

With Rob Rix' statement in mind that the style guide should pay special attention to less experienced programmers, a naming convention that most of us follow but isn't documented is to end symbol names in the class or primitive type they represent.

This is especially important when dealing with a variable that is not precisely the semantic type it sounds like:

  • NSString *URLstring = [self.item.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  • NSURL *URL = [NSURL URLWithString:URLstring];
  • NSString *apiReleaseDateString = [currentAPIDict valueForKey:@"date"];
  • NSDate *apiReleaseDate = [DateFormatter dateFromString:apiReleaseDateString];

Convention for using NSLog()

Is there a convention for using NSLog(), I find it useful to prefix logging with the class name (can even go further and add a prefix with the method).

Switch-case

I would be happy if you'd enhance this doc to include some guidelines about switch-case control structures, especially the ones with {} blocks.

Booleans - explicit nil comparison

For quite some time I used to omit the nil comparison, as described here:
https://github.com/NYTimes/objective-c-style-guide#booleans

However it is easy to get too enthusiastic and slip a (nasty to track down) bug in like this:

@property (nonatomic, strong) MYSocket *socket;
- (BOOL)isSocketReady {
     return socket;
}

Instead of:

@property (nonatomic, strong) MYSocket *socket;
- (BOOL)isSocketReady {
     return socket != nil;
}

Saying that nil resolves to NO might give the wrong impression.
More correct would be: the if statement determines if the argument is not 0 and nil is defined as (id) 0, that's why it works.

More info on nil: http://nshipster.com/nil/
More info on BOOL: http://nshipster.com/bool/

Add an exception to naming convention for names beginning with commonly used abbrevations

The Naming section advises

Properties should be camel-case with the leading word being lowercase.

When it makes sense for a symbol name to begin with a commonly used abbreviation, then the abbreviation should be capitalized according to common convention. In other words, the common naming convention takes precedence.

Examples appear scattered through Apple's class references:

  • NSData *HTTPBody
  • NSURL *URL
  • const char *UTF8String
  • [UIColor RedColor].CGColor

Dot notation in Booleans example

In the Booleans section the example reads:

if ([someObject boolValue] == NO)

But in Dot-Notation, it says "Dot-notation should always be used for accessing and mutating properties".

So shouldn't the example read:
if (someObject.boolValue == NO)

Conditionals Assertion: Citation Needed

"Conditional bodies should always use braces even when a conditional body could be written without braces (i.e., it is one line only) braces should still be used. There are just too many little ways to get burned otherwise."

Please elaborate with at least one way to get burned that doesn't exist independently of bracing one-line conditional bodies. Otherwise, this is merely dogma and should at least be labeled "because we say so". Example: "...because then you might accidentally add a line after it that you expect to be part of the conditional." To which I'd say, "bullshit - the editor highlight this with its auto-indentation (because all code-aware editors I've used 'correctly' indent one-liners and not subsequent lines) and therefore this "problem" was solved long ago by a much higher and much-more-deeply-entrenched standard.

While I've never been a fan of the truly one-line if (someCondition) someExpression(); style because I prefer seeing an indentation to set off a body visually, I see nothing wrong with one-line bodies without braces after the test. In fact, it's more succinct and takes much less effort when scanning code with the eyes than all the visual weight of a braced body (the braces, of course, being there specifically because a way to group is needed).

So: my issue is mainly with the unbacked assertion that unbraced conditional bodies are somehow more dangerous than adding extraneous characters for a body that may never grow beyond that single line. It seems more like premature optimization and over-engineering to me.

Dot notation for methods that should be properties

I assert that in the Apple frameworks, things like -count and -length should be read-only properties, and would be, were they written today (I'll accept "you're dead wrong" from Dave DeLong or other credible sources)

It seems that the compiler agrees with me, because it no longer warns about myArray.count as I am almost positive that it once did (I recall a warning against using "unintended side-effects" or something).

So someone explain to me why we shouldn't just use dot-notation getters for these "property-like" methods.

One counter argument might be: Who will decide which methods are "property-like"? To which I answer, I know them when I see them. They describe a property of an object (that's "property" without an @).

Challenge on private properties rule

When unit testing a class it is often useful to expose its private properties.

@interface MyClass ()
@property (nonatomic) NSString * internalProperty;
@end

@implementation MyClass
 // ...
@end

How do you make myClass.internalProperty available in the test spec?

The way I see it there are 2 options

  1. Duplicate the anonymous category at the top of the spec file (this is bad practice as you may change one anonymous category but forget to change the other).
  2. Put the anonymous category in a file called MyClass_Private.h and include it in both MyClass.h and MyClassSpec.h. However this approach is forbidden in the rules.

Do you have any suggestions?

Newline-then-bracket for method implementation?

Does NYT have a specific style for where a bracket should appear after a method name in the .m file? For example, which one of these do you use?

A:

- (void)viewDidLoad
{
    [super viewDidLoad];
}

or B:

- (void)viewDidLoad {
    [super viewDidLoad];
}

I use A for methods, but use curly-brackets on the same line for any kind of structure within the method (conditionals, loops, etc).

Ternary operator example

The two examples for the ternary operator are not functionally equivalent

result = a > b ? x : y;

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

Including Boxed enums in "Literals" Section?

Was hoping to add the following convention for boxed enums (described here). I figure trying to create a dictionary with enums would require the use of numberWithInt: or numberWithInteger:, so this would align with the current conventions.

typedef NS_ENUM(NSInteger, NYTDaysOfTheWeek){
     NYTMonday = 0, 
     NYTTuesday,
     NYTWednesday
};
NSDictionary * daysOfTheWeek = @{ @"monday" : @(NYTMonday), 
                                 @"tuesday" : @(NYTTuesday), 
                               @"wednesday" : @(NYTWednesday) };

let me try it

本月要做的任务

  • 完成图片
  • 完成部署工具的设置
  • 实现抽签功能
    fix#23

"Dot-notation should always be used for accessing and mutating properties. Bracket notation is preferred in all other instances."

Dot notation obscures the exact nature of what you are doing with a property. It also provides a way to confuse structs with objects, which can lead to especially subtle and maddening bugs.

An example with NSView's Frame properties:

view.frame.size = blah; //does nothing.
view.frameSize = blah; //does something.

The Big Nerd Ranch (one of the foremost experts in OBJ-C, imho) has an excellent article about this very thing.

The QualityCoding blog also has a great article on why dot-notation is evil.

And to top it off, the excellent cocoa blog Cocoa Is My Girlfriend has a case against dot-notation.

edit: added links

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.