├── AppCodeStyleScheme.jar ├── README.md └── uncrustify.cfg /AppCodeStyleScheme.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobotsAndPencils/objective-c-style-guide/c01cf90a85d9b1b71c8237bf42bbdd650cec3239/AppCodeStyleScheme.jar -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Robots & Pencils Objective-C Style Guide 2 | 3 | This documents the coding style adhered to at Robots & Pencils, enjoy! Feel free to open a pull request if you think we are missing anything or would like to debate existing points. 4 | 5 | **Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)* 6 | 7 | - [Whitespace](#whitespace) 8 | - [Organization](#organization) 9 | - [Comments](#comments) 10 | - [Literals](#literals) 11 | - [Declarations](#declarations) 12 | - [Private Properties](#private-properties) 13 | - [Expressions](#expressions) 14 | - [Control Structures](#control-structures) 15 | - [Exceptions and Error Handling](#exceptions-and-error-handling) 16 | - [Blocks](#blocks) 17 | - [Singletons](#singletons) 18 | - [Code Naming](#code-naming) 19 | - [Good](#good) 20 | - [Bad](#bad) 21 | - [Method Signatures](#method-signatures) 22 | - [Use lower camel case](#use-lower-camel-case) 23 | - [Start with action](#start-with-action) 24 | - [Getters](#getters) 25 | - [Return Type Spacing](#return-type-spacing) 26 | - [Parameter Keywords](#parameter-keywords) 27 | - [Be Descriptive](#be-descriptive) 28 | - [Avoid And (With Exceptions)](#avoid-and-with-exceptions) 29 | - [Signature Spacing](#signature-spacing) 30 | - [Classes](#classes) 31 | - [Namespace prefixes](#namespace-prefixes) 32 | - [Booleans](#booleans) 33 | - [Properties](#properties) 34 | - [Pointer Spacing](#pointer-spacing) 35 | - [@synthesize and @dynamic](#@synthesize-and-@dynamic) 36 | - [@property](#@property) 37 | - [Enums](#enums) 38 | - [xib Files](#xib-files) 39 | - [Golden Path](#golden-path) 40 | - [More on Brackets](#more-on-brackets) 41 | - [Memory Management](#memory-management) 42 | - [Boyscout / Girl Guide](#boyscout--girl-guide) 43 | - [Copyrights](#copyrights) 44 | - [Proper Code Nutrition](#proper-code-nutrition) 45 | - [Integers](#integers) 46 | - [Floats](#floats) 47 | - [Strings](#strings) 48 | - [Inspiration](#inspiration) 49 | 50 | Whitespace 51 | ========== 52 | 53 | * Indent using 4 spaces. Never indent with tabs. Be sure to set this preference in Xcode (Xcode defaults to 4 spaces). 54 | 55 | * Separate imports from the rest of your file by 1 space. Optionally group imports if there are many (but try to have less dependencies). Generally strive to include frameworks first. 56 | 57 | ``` obj-c 58 | #import 59 | #import 60 | 61 | #import "SomeDependency.h" 62 | #import "SomeOtherDependency.h" 63 | 64 | @interface MyClass 65 | ``` 66 | 67 | * Use one empty line between class extension and implementation in .m file. 68 | 69 | ``` obj-c 70 | @interface MyClass () 71 | 72 | // Properties - empty line above and below 73 | 74 | @end 75 | 76 | @implementation MyClass 77 | 78 | // Body - empty line above and below 79 | 80 | @end 81 | 82 | ``` 83 | 84 | * Always end a file with a newline. 85 | 86 | ![](http://cl.ly/image/2g3b0C2a3F0c/Image%202014-11-14%20at%2010.51.17%20AM.png) 87 | 88 | * When using pragma marks leave 1 newline before and after. 89 | 90 | ``` obj-c 91 | - (CGSize)intrinsicContentSize { 92 | return CGSizeMake(12, 12); 93 | } 94 | 95 | #pragma mark - Private 96 | 97 | - (void)setup { 98 | [self addGestureRecognizer:[[NSClickGestureRecognizer alloc] initWithTarget:self action:@selector(clicked:)]]; 99 | } 100 | ``` 101 | 102 | * When doing math use a single space between operators. Unless that operator is unary in which case don't use a space. 103 | 104 | ```obj-c 105 | NSInteger index = rand() % 50 + 25; // arc4random_uniform(50) should be used insted of `rand() % 50`, but doesn't illustrate the principle well 106 | index++; 107 | index += 1; 108 | index--; 109 | ``` 110 | 111 | * When doing logic, a single space should follow the `if` and a single space should preceed the `{` 112 | 113 | ``` obj-c 114 | if (alpha + beta <= 0) && (kappa + phi > 0) { 115 | } 116 | ``` 117 | 118 | * Colon-aligning method invocation should often be avoided. There are cases where a method signature may have >= 3 colons and colon-aligning makes the code more readable. Please do **NOT** however colon align methods containing blocks because Xcode's indenting makes it illegible. 119 | 120 | Good: 121 | 122 | ```objc 123 | // blocks are easily readable 124 | [UIView animateWithDuration:1.0 animations:^{ 125 | // something 126 | } completion:^(BOOL finished) { 127 | // something 128 | }]; 129 | ``` 130 | 131 | Bad: 132 | 133 | ```objc 134 | // colon-aligning makes the block indentation wacky and hard to read 135 | [UIView animateWithDuration:1.0 136 | animations:^{ 137 | // something 138 | } 139 | completion:^(BOOL finished) { 140 | // something 141 | }]; 142 | ``` 143 | 144 | * Whitespace should in *all* cases be used to aid readability. Readability is highly subjective, so here are some rough guides: 145 | * Use new lines to delimit chunks of related code (approx 4-5 lines). If more than 4-5 lines are grouped, consider refactoring those lines into another method. 146 | * By grouping related lines of code it naturally starts to show where the method can be refactored into smaller reusable units 147 | * One blank line is generally sufficient. 148 | * Avoid extraneous new lines between nested sets of parenthesis. 149 | * Avoid blank lines at the end of methods. (Consider delimiting the final return value with one though.) 150 | 151 | Good: 152 | 153 | ```objc 154 | - (void)awakeFromNib { 155 | UIStoryboard *signatureStoryboard = [UIStoryboard storyboardWithName:@"BBPopoverSignature" bundle:nil]; 156 | self.signatureViewController = [signatureStoryboard instantiateViewControllerWithIdentifier:@"BBPopoverSignature"]; 157 | self.signatureViewController.modalPresentationStyle = UIModalPresentationPopover; 158 | self.signatureViewController.preferredContentSize = CGSizeMake(BBPopoverSignatureWidth, BBPopoverSignatureHeight); 159 | self.signatureViewController.signatureImageView = self; 160 | 161 | UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(initiateSignatureCapture)]; 162 | [self addGestureRecognizer:tapRecognizer]; 163 | } 164 | ``` 165 | Note: 166 | 167 | 1. all the `signatureViewController`-related lines are together 168 | 2. the new line delimits the end of configuration of `signatureViewController` 169 | 3. the `tapRecognizer` instantiation and configuration is grouped, and not mixed with unrelated code 170 | 4. a new line after the opening `{` and a new line before the closing `}` are permissible. In some cases they aid readability and in others they yield an overabundance of whitespace. 171 | 172 | Good: 173 | ```objc 174 | - (NSAttributedString *)aboutTermsAttributedString { 175 | 176 | NSDictionary *attributes = nil; 177 | NSError *error = nil; 178 | 179 | NSURL *fileURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"terms_of_use" ofType:@"html"]]; 180 | NSAttributedString *attributedString = [[NSAttributedString alloc] initWithFileURL:fileURL 181 | options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: @(NSUTF8StringEncoding)} 182 | documentAttributes:&attributes 183 | error:&error]; 184 | if (error) { 185 | NSLog(@"Error: unable to load about mobile string. %@", [error localizedDescription]); 186 | return nil; 187 | } 188 | 189 | return attributedString; 190 | } 191 | ``` 192 | Note: 193 | 194 | 1. blank line after the opening `{` of the method helps give the local variables their own context 195 | 2. complexity of `attributedString` initialization is more readable with colon aligning 196 | 3. final return value is immediately clear thanks to the blank line above it 197 | 198 | Good: 199 | ```objc 200 | 201 | @interface BBProofOfLossViewController () 202 | 203 | @property (strong, nonatomic) NSArray *targetItems; 204 | @property (strong, nonatomic) BBCustomForm *customForm; 205 | 206 | @property (weak, nonatomic) IBOutlet UILabel *nameLabel; 207 | @property (weak, nonatomic) IBOutlet UILabel *addressLabel; 208 | @property (weak, nonatomic) IBOutlet UILabel *fooLabel; 209 | @property (weak, nonatomic) IBOutlet UILabel *barLabel; 210 | @property (weak, nonatomic) IBOutlet UILabel *instanceNumberLabel; 211 | @property (weak, nonatomic) IBOutlet UILabel *relatedNumberLabel; 212 | @property (weak, nonatomic) IBOutlet UILabel *bazLabel; 213 | @property (weak, nonatomic) IBOutlet UILabel *typeOfInstanceLabel; 214 | @property (weak, nonatomic) IBOutlet UILabel *dateLabel; 215 | 216 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *itemListHeightConstraint; 217 | 218 | @property (weak, nonatomic) IBOutlet BBAutocompletePopoverDateTextField *formDatePopoverTextField; 219 | 220 | @property (weak, nonatomic) IBOutlet BBPopoverSignatureImageView *witnessSignatureImageView; 221 | @property (weak, nonatomic) IBOutlet UITextField *witnessSignatureBackgroundTextField; 222 | @property (weak, nonatomic) IBOutlet UILabel *witnessNameLabel; 223 | @property (weak, nonatomic) IBOutlet UILabel *witnessLocationLabel; 224 | @property (weak, nonatomic) IBOutlet UILabel *witnessDateLabel; 225 | 226 | @property (weak, nonatomic) IBOutlet BBPopoverSignatureImageView *submitterSignatureImageView; 227 | @property (weak, nonatomic) IBOutlet UITextField *submitterSignatureBackgroundTextField; 228 | @property (weak, nonatomic) IBOutlet UILabel *submitterNameLabel; 229 | @property (weak, nonatomic) IBOutlet UILabel *submitterLocationLabel; 230 | @property (weak, nonatomic) IBOutlet UILabel *submitterDateLabel; 231 | 232 | @property (weak, nonatomic) IBOutlet BBPopoverSignatureImageView *authorizerSignatureImageView; 233 | @property (weak, nonatomic) IBOutlet UITextField *authorizerSignatureBackgroundTextField; 234 | @property (weak, nonatomic) IBOutlet UILabel *authorizerNameLabel; 235 | @property (weak, nonatomic) IBOutlet UILabel *authorizerLocationLabel; 236 | @property (weak, nonatomic) IBOutlet UILabel *authorizerDateLabel; 237 | 238 | @end 239 | 240 | ``` 241 | Note: 242 | 243 | 1. new line after the `@interface` and before the `@end` 244 | 2. properties that are *not* `IBOutlet`s are grouped 245 | 3. `IBOutlet` properties are grouped by context 246 | 4. the patterns in the grouping aid readability by allowing the eye to see inconsistencies (there are none in this case) 247 | 248 | Bad: 249 | ```objc 250 | 251 | - (void)viewController:(BBViewController *)viewController 252 | finishedWithAuth:(BBAuthentication *)auth 253 | error:(NSError *)error { 254 | 255 | //pushViewController didn't work, use ugly full screen view 256 | [viewController dismissViewControllerAnimated:YES completion:nil]; 257 | 258 | if (error != nil) { 259 | 260 | NSLog(@"Authentication failed %@", [error description]); 261 | 262 | } else { 263 | 264 | NSString *apiURL = @"https://api.example.com/v1/quux/~?format=json"; 265 | 266 | NSURL *url = [NSURL URLWithString:apiURL]; 267 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 268 | 269 | [auth authorizeRequest:request completionHandler:^(NSError *error) { 270 | 271 | AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 272 | operation.responseSerializer = [AFJSONResponseSerializer serializer]; 273 | [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 274 | 275 | NSDictionary *responseData = (NSDictionary *)responseObject; 276 | RBKQuickAlert(@"Response description", responseData.description); 277 | 278 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 279 | 280 | RBKQuickAlert(@"Response error", error.description); 281 | 282 | }]; 283 | 284 | [operation start]; 285 | 286 | }]; 287 | 288 | } 289 | 290 | } 291 | ``` 292 | Note: 293 | 294 | 1. method colons aren't aligned. (Method signature is not well suited to colon aligning) 295 | 2. Happy path is nested. (Early return is missing) 296 | 3. Lots of extra blank lines that break up readability. (Whitespace is failing to define context) 297 | 4. URL string is hardcoded (not environment-aware) 298 | 5. `NSMutableURLRequest` instantiation is spread over several lines 299 | 300 | Bad rewritten better: 301 | 302 | ```objc 303 | 304 | // DEV_BUILD/STAGE_BUILD/PROD_BUILD are configured in Project Build Settings Preprocessor Macros 305 | #if DEV_BUILD 306 | static NSString * const BBAPIBaseURLString = @"https://dev.example.com/v1/quux/~?format=json"; // dev 307 | 308 | #elif QA_BUILD 309 | static NSString * const BBAPIBaseURLString = @"https://qa.example.com/v1/quux/~?format=json"; // qa 310 | 311 | #elif STAGE_BUILD 312 | static NSString * const BBAPIBaseURLString = @"https://stage.example.com/v1/quux/~?format=json"; // stage 313 | 314 | #elif PROD_BUILD 315 | static NSString * const BBAPIBaseURLString = @"https://api.example.com/v1/quux/~?format=json"; // prod 316 | 317 | #else 318 | static NSString * const BBAPIBaseURLString = @"https://api.example.com/v1/quux/~?format=json"; // prod 319 | 320 | #endif 321 | 322 | - (void)viewController:(BBViewController *)viewController finishedWithAuth:(BBAuthentication *)auth error:(NSError *)error { 323 | 324 | //pushViewController didn't work, use ugly full screen view 325 | [viewController dismissViewControllerAnimated:YES completion:nil]; 326 | 327 | if (error) { 328 | NSLog(@"Authentication failed %@", [error localizedDescription]); 329 | 330 | // TODO: call our own completion block with this error? 331 | 332 | return; 333 | } 334 | 335 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:BBAPIBaseURLString]]; // mutable in case we need to adjust the request headers 336 | [auth authorizeRequest:request completionHandler:^(NSError *error) { 337 | 338 | // we should probably be checking the supplied error to decided if we need to do this operation or not 339 | 340 | AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; 341 | operation.responseSerializer = [AFJSONResponseSerializer serializer]; 342 | [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 343 | NSDictionary *responseData = (NSDictionary *)responseObject; 344 | 345 | // TODO: Handle our response data. Call our own completion block? 346 | 347 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 348 | NSLog(@"Error: %@", error.localizedDescription); 349 | 350 | // TODO: call our own completion block when we have an error? 351 | }]; 352 | 353 | [operation start]; 354 | }]; 355 | } 356 | ``` 357 | Note: This method is obviously incomplete and may not, *architecturally* be optimal, however it can be still styled in a readable manner. 358 | 359 | Organization 360 | ============ 361 | 362 | * use `#pragma mark -`s to categorize methods in functional groupings and protocol/delegate implementations following this general structure. 363 | 364 | ```objc 365 | #pragma mark - Lifecycle 366 | 367 | + (instancetype)objectWithThing:(id)thing {} 368 | - (instancetype)init {} 369 | - (void)dealloc {} 370 | - (void)viewDidLoad {} 371 | - (void)didReceiveMemoryWarning {} 372 | 373 | #pragma mark - Custom Accessors 374 | 375 | - (void)setCustomProperty:(id)property {} 376 | - (id)anotherCustomProperty {} 377 | 378 | #pragma mark - Actions 379 | 380 | - (IBAction)submitData:(id)sender {} 381 | 382 | #pragma mark - Public 383 | 384 | - (void)publicMethod {} 385 | 386 | #pragma mark - Private 387 | 388 | - (void)privateMethod {} 389 | 390 | #pragma mark - Protocol conformance 391 | #pragma mark - UITextFieldDelegate 392 | #pragma mark - UITableViewDataSource 393 | #pragma mark - UITableViewDelegate 394 | 395 | #pragma mark - NSCopying 396 | 397 | - (id)copyWithZone:(NSZone *)zone {} 398 | 399 | #pragma mark - NSObject 400 | 401 | - (NSString *)description {} 402 | ``` 403 | 404 | Comments 405 | ======== 406 | 407 | 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. 408 | 409 | Block comments should generally be avoided, as code should be as self-documenting as possible, with only the need for intermittent, few-line explanations. *Exception: comments used to generate documentation.* 410 | 411 | Literals 412 | ======== 413 | 414 | `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. 415 | 416 | Good: 417 | 418 | ```objc 419 | NSArray *names = @[@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul"]; 420 | NSDictionary *productManagers = @{@"iPhone" : @"Kate", @"iPad" : @"Kamal", @"Mobile Web" : @"Bill"}; 421 | NSNumber *shouldUseLiterals = @YES; 422 | NSNumber *buildingZIPCode = @10018; 423 | ``` 424 | 425 | Bad: 426 | 427 | ```objc 428 | NSArray *names = [NSArray arrayWithObjects:@"Brian", @"Matt", @"Chris", @"Alex", @"Steve", @"Paul", nil]; 429 | NSDictionary *productManagers = [NSDictionary dictionaryWithObjectsAndKeys: @"Kate", @"iPhone", @"Kamal", @"iPad", @"Bill", @"Mobile Web", nil]; 430 | NSNumber *shouldUseLiterals = [NSNumber numberWithBool:YES]; 431 | NSNumber *buildingZIPCode = [NSNumber numberWithInteger:10018]; 432 | ``` 433 | 434 | Declarations 435 | ============ 436 | 437 | * Always declare memory-management semantics even on `readonly` properties. List the management semantics first for consistency (and to match XCode default). 438 | 439 | Good: 440 | 441 | ```objc 442 | @property (assign, nonatomic) NSInteger statusCode; 443 | ``` 444 | 445 | Bad: 446 | 447 | ```objc 448 | @property (nonatomic) NSInteger statusCode; 449 | ``` 450 | 451 | * Don't use @synthesize unless the compiler requires it. Note that optional properties in protocols must be explicitly synthesized in order to exist. 452 | * Instance variables should be prefixed with an underscore (just like when implicitly synthesized). 453 | 454 | Good: 455 | 456 | ```objc 457 | @synthesize statusCode = _statusCode; 458 | ``` 459 | 460 | Bad: 461 | 462 | ```objc 463 | @synthesize statusCode; 464 | ``` 465 | 466 | * Don't put a space between an object type and the protocol it conforms to. 467 | 468 | Good: 469 | 470 | ```objc 471 | @property (weak, nonatomic) id analyticsDelegate; 472 | ``` 473 | 474 | Bad: 475 | 476 | ```objc 477 | @property (nonatomic) id analyticsDelegate; 478 | ``` 479 | 480 | Private Properties 481 | ================== 482 | 483 | Private properties should be declared in class extensions (anonymous categories) in the implementation file of a class. Named categories, used when extending an existing class (e.g. `NSString`), should not be confused with class extensions. 484 | 485 | For example: 486 | 487 | ```objc 488 | @interface VPDetailViewController () 489 | 490 | @property (strong, nonatomic) GADBannerView *googleAdView; 491 | @property (strong, nonatomic) ADBannerView *iAdView; 492 | @property (strong, nonatomic) UIWebView *adXWebView; 493 | 494 | @end 495 | ``` 496 | 497 | Expressions 498 | =========== 499 | 500 | * Don't access an ivar unless you're in `-init`, `-dealloc` or a custom accessor. 501 | * Only use dot syntax to access properties, not to call methods 502 | 503 | Good: 504 | 505 | ```objc 506 | view.frame 507 | ``` 508 | 509 | Bad: 510 | 511 | ```objc 512 | [view frame] 513 | ``` 514 | 515 | Good: 516 | 517 | ```objc 518 | self.view.frame = CGRectMake(x, y, width, height); 519 | [self.view removeFromSuperview]; 520 | 521 | Person *selectedPerson = [self getPersonWithId:idNumber]; 522 | self.nameLabel.text = selectedPerson.name; 523 | 524 | - (void)setProperty:(id)newValue { 525 | _property = newValue; 526 | [self someOtherMethod]; 527 | } 528 | ``` 529 | 530 | Bad: 531 | 532 | ```objc 533 | [[self view] setFrame:CGRectMake(x, y, width, height)]; 534 | [_view removeFromSuperview]; 535 | 536 | self.nameLabel.text = [self getPersonWithId:idNumber].name; 537 | ``` 538 | 539 | * Similarly, use dot syntax to get or set properties over explicit message sending. 540 | * Also, use `NSInteger` or `NSUInteger` over `int`. 541 | 542 | Good: 543 | 544 | ```objc 545 | NSUInteger numberOfItems = sampleArray.count; 546 | 547 | sampleView.backgroundColor = [UIColor greenColor]; 548 | ``` 549 | 550 | Bad: 551 | 552 | ```objc 553 | int numberOfItems = [sampleArray count]; // using int and explicit message sending 554 | 555 | [sampleView setBackgroundColor:[UIColor greenColor]]; // explicit message sending 556 | ``` 557 | 558 | * Use object literals, boxed expressions, and subscripting over the older, grosser alternatives. 559 | * Separate binary operands with a single space, but unary operands and casts with none: 560 | 561 | ```objc 562 | void *ptr = &value + 10 * 3; 563 | NewType a = (NewType)b; 564 | 565 | for (NSInteger i = 0; i < 10; i++) { 566 | doCoolThings(); 567 | } 568 | ``` 569 | 570 | Control Structures 571 | ================== 572 | 573 | * Always surround `if` bodies with curly braces if there is an `else`. Single-line `if` bodies without an `else` should be on the same line as the `if`. 574 | 575 | * All curly braces should begin on the same line as their associated statement. They should end on a new line. [1TBS](http://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS "1TBS") 576 | * Put a single space after keywords and before their parentheses. 577 | * Return and break early. 578 | * No spaces between parentheses and their contents. 579 | 580 | ```objc 581 | if (!goodCondition) return; 582 | 583 | if (condition == YES) { 584 | // do stuff 585 | } else { 586 | // do other stuff 587 | } 588 | ``` 589 | 590 | If the name of a BOOL property is expressed as an adjective, the property can omit the “is” prefix but specifies the conventional name for the get accessor, for example: 591 | 592 | ```objc 593 | @property (assign, getter=isEditable) BOOL editable; 594 | ``` 595 | 596 | Exceptions and Error Handling 597 | ============================= 598 | * Don't use exceptions for flow control. 599 | * Use exceptions **only** to indicate programmer error. 600 | * To indicate errors, use an `NSError **` argument . 601 | 602 | 603 | Blocks 604 | ====== 605 | 606 | * Blocks should have a space between their return type and name. 607 | * Block definitions should omit their return type when possible. 608 | * Block definitions should omit their arguments if they are void. 609 | * Parameters in block types should be named unless the block is initialized immediately. 610 | 611 | ```objc 612 | void (^blockName1)(void) = ^{ 613 | // do some things 614 | }; 615 | 616 | id (^blockName2)(id) = ^ id (id args) { 617 | // do some things 618 | }; 619 | ``` 620 | 621 | Singletons 622 | ========== 623 | Singleton objects should use a thread-safe pattern for creating their shared instance. 624 | 625 | ```objc 626 | + (instancetype)sharedInstance { 627 | static id sharedInstance = nil; 628 | 629 | static dispatch_once_t onceToken; 630 | dispatch_once(&onceToken, ^{ 631 | sharedInstance = [[self alloc] init]; 632 | }); 633 | 634 | return sharedInstance; 635 | } 636 | ``` 637 | 638 | Code Naming 639 | =========== 640 | Good 641 | ---- 642 | * Clear, expressive, non-ambiguous names. 643 | Since you do far more reading of code than writing, invest the time to type an extra eight characters (and then leverage autocomplete). 644 | 645 | Bad 646 | --- 647 | * Hungarian notation 648 | 649 | e.g. data type as part of name `strUserName` 650 | 651 | Exception: `const` or `enum` values should follow Apple's class-name-then-least-to-most specific pattern. e.g. `UIDeviceOrientationLandscapeRight` or `VPNavigationBarHeight_iPad`). 652 | * Abbreviating. Lazy naming. 653 | 654 | e.g `index` What index? 655 | For an array of house objects use `houseIndex` 656 | 657 | Method Signatures 658 | ================= 659 | Use lower camel case 660 | -------------------- 661 | 662 | Good: 663 | 664 | ```objc 665 | answerViewController 666 | ``` 667 | 668 | Bad: 669 | 670 | ```objc 671 | answer_view_controller 672 | ``` 673 | 674 | Start with action 675 | ----------------- 676 | For methods that represent an action an object takes, start the name with the action. 677 | 678 | Good: 679 | 680 | ```objc 681 | - (IBAction)showDetailViewController:(id)sender 682 | ``` 683 | 684 | Bad: 685 | 686 | ```objc 687 | - (void)detailButtonTapped:(id)sender 688 | ``` 689 | 690 | Getters 691 | ------- 692 | If the method returns an attribute of the receiver, name the method after the attribute. The use of "get" is unnecessary, unless one or more values are returned via indirection. 693 | 694 | Good: 695 | 696 | ```objc 697 | - (NSInteger)age 698 | ``` 699 | 700 | Bad: 701 | 702 | ```objc 703 | - (NSInteger)calcAge 704 | - (NSInteger)getAge 705 | ``` 706 | 707 | Return Type Spacing 708 | ------------------- 709 | For consistency method definitions should have a space between the + or - (scope) and the return type (matching Apple's style). 710 | 711 | Good: 712 | 713 | ```objc 714 | - (int)age 715 | ``` 716 | 717 | Bad: 718 | 719 | ```objc 720 | -(int)age 721 | -(int) age 722 | ``` 723 | 724 | Parameter Keywords 725 | ------------------ 726 | Use keywords before all parameters. 727 | 728 | Good: 729 | 730 | ```objc 731 | - (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag; 732 | ``` 733 | 734 | Bad: 735 | 736 | ```objc 737 | - (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag; 738 | ``` 739 | 740 | Be Descriptive 741 | -------------- 742 | Make the word before the argument describe the argument. 743 | 744 | Good: 745 | 746 | ```objc 747 | - (id)viewWithTag:(NSInteger)tag; 748 | ``` 749 | 750 | Bad: 751 | 752 | ```objc 753 | - (id)taggedView:(NSInteger)tag; 754 | ``` 755 | 756 | **Note: this is a poor example because in general tags are an antipattern and should be avoided if at all possible**. 757 | 758 | Avoid And (With Exceptions) 759 | --------------------------- 760 | Do not use "and" to link keywords that are attributes of the receiver. 761 | 762 | Good: 763 | 764 | ```objc 765 | - (NSInteger)runModalForDirectory:(NSString *)path file:(NSString *)name types:(NSArray *)fileTypes; 766 | ``` 767 | 768 | Bad: 769 | 770 | ```objc 771 | - (NSInteger)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes; 772 | ``` 773 | 774 | **Exception:** if the method describes *two separate actions*, use "and" to link them: 775 | 776 | ```objc 777 | - (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag; 778 | ``` 779 | 780 | Signature Spacing 781 | --------------- 782 | Method parameters should not have a space between the keyword and the parameter. 783 | 784 | Good: 785 | 786 | ```objc 787 | - (void)setExample:(NSString *)text; 788 | ``` 789 | 790 | 791 | Bad: 792 | 793 | ```objc 794 | - (void)setExample: (NSString *)text; 795 | - (void)setExample:(NSString *) text; 796 | ``` 797 | 798 | Init Methods 799 | --------------- 800 | Init methods should return `instancetype` instead of `id`. Generally this is the one place ivars should be used instead of properties because the class may be in an inconsistent state until it is fully initialized. 801 | 802 | ```objc 803 | - (instancetype)init { 804 | self = [super init]; 805 | if (self) { 806 | // ... 807 | } 808 | return self; 809 | } 810 | ``` 811 | 812 | Dealloc Methods 813 | --------------- 814 | Dealloc methods are no longer required when using arc but in certain cases must be used to remove observers, KVO, etc. 815 | 816 | ```objc 817 | - (void)dealloc{ 818 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 819 | } 820 | ``` 821 | 822 | 823 | Classes 824 | ======= 825 | Class names use upper camel case, ie First word capitalized, start of new words capitalized as well. In general there should be one class per .h/.m file. 826 | 827 | ```objc 828 | SVSSpy 829 | SVSWhiteSpy 830 | SVSBlackSpy 831 | SVSCar 832 | SVSCarEngine 833 | ``` 834 | 835 | Namespace prefixes 836 | ================== 837 | 838 | Descriptive names should generally avoid conflicts, however there are tangible benefits to using three character class name prefixes e.g. `RBKObjectSerialization`. Class name prefixes can be used to: 839 | 840 | * filter visible files in the project navigator in Xcode 841 | * allow you to ignore search results in files without your desired prefix 842 | * convey the ancestry of the class (as sometimes classes have been reused between projects) 843 | * distinguish between components of the app 844 | 845 | Shared code should be definitely be prefixed (e.g. in RoboKit). 846 | 847 | Class name prefixes may be avoided for CoreData entity names. 848 | 849 | Avoid using overly simple names like "Model" "View" "Object". 850 | 851 | When you don't prefix and you have a namespace collision they're megahard to debug and unravel. 852 | 853 | Booleans 854 | ======== 855 | Objective-C uses `YES` and `NO`. Therefore `true` and `false` should only be used for CoreFoundation, C or C++ code. Since `nil` resolves to `NO` it is unnecessary to compare it in conditions. 856 | 857 | Good: 858 | 859 | ```objc 860 | if (someObject) {} 861 | if (![anotherObject boolValue]) {} 862 | ``` 863 | 864 | Bad: 865 | 866 | ```objc 867 | if (someObject == nil) {} 868 | if ([anotherObject boolValue] == NO) {} 869 | ``` 870 | 871 | Properties 872 | ========== 873 | Pointer Spacing 874 | --------------- 875 | The `*` should be **nearest** the variable, not the type. 876 | 877 | Good: 878 | 879 | ```objc 880 | NSString *text = @"foo"; 881 | ``` 882 | 883 | Bad: 884 | 885 | ```objc 886 | NSString * text = @"foo"; 887 | NSString* text = @"foo"; 888 | ``` 889 | 890 | @synthesize and @dynamic 891 | ------------------------ 892 | 893 | *Note: as of Xcode 4.4/4.5 `@synthesize` should be removed with some exceptions. See (http://useyourloaf.com/blog/2012/08/01/property-synthesis-with-xcode-4-dot-4.html) "When To Supply The Instance Variable" for clarity* 894 | 895 | `@synthesize` and `@dynamic` should go directly beneath `@implementation` where each `@synthesize` and `@dynamic` should be on a single line. 896 | 897 | When synthesizing the instance variable, use `@synthesize var = _var;` as this prevents accidentally calling `var = blah;` when `self.var = blah;` is correct. 898 | 899 | @property 900 | --------- 901 | 902 | Property definitions should be used in place of ivars. When defining properties, put strong/weak/retain/assign first then nonatomic for consistency. 903 | 904 | ```objc 905 | @property (weak, nonatomic) IBOutlet UIWebView *messageWebView; 906 | ``` 907 | 908 | *Note: IBOutlets should be `weak` unless they are a top-level item in a xib (e.g. the top-level view is `strong`, anything beneath it is `weak`) 909 | 910 | Info about the overhead and performance of properties vs ivars can be found [here](http://blog.bignerdranch.com/4005-should-i-use-a-property-or-an-instance-variable/). 911 | 912 | 913 | Enums 914 | ====== 915 | Magic numbers that are integers should be stored in an enum. If you want to use it as a type, you can make it a type: 916 | 917 | ```objc 918 | typedef NS_ENUM(NSUInteger, VPLeftMenuTopItemType) { 919 | VPLeftMenuTopItemTypeMain = 0, 920 | VPLeftMenuTopItemTypeShows, 921 | VPLeftMenuTopItemTypeSchedule, 922 | VPLeftMenuTopItemTypeWatchLive, 923 | VPLeftMenuTopItemTypeMax, 924 | }; 925 | ``` 926 | 927 | In this case each successive item in the enum will have an integer value greater than the previous item. 928 | 929 | Naming in this ^ style also makes the enum Swift-compatible. (e.g. `.Main`, `.WatchLive`) 930 | 931 | You can also make explicit value assignments: 932 | 933 | ```objc 934 | typedef NS_ENUM(NSInteger, RBKGlobalConstants) { 935 | RBKPinSizeMin = 1, 936 | RBKPinSizeMax = 5, 937 | RBKPinCountMin = 100, 938 | RBKPinCountMax = 500, 939 | }; 940 | ``` 941 | 942 | 943 | Older k-style constant definitions should be **avoided** unless writing CoreFoundation C code (unlikely). 944 | 945 | Bad: 946 | 947 | ```objc 948 | enum GlobalConstants { 949 | kMaxPinSize = 5, 950 | kMaxPinCount = 500, 951 | }; 952 | ``` 953 | 954 | xib Files 955 | ========= 956 | xib files should always be saved in their language-specific folders. The default folder for English is `en.lproj`. 957 | xib file names should end in `view`, `menu` or `window` but never `controller` (as xibs are *not* controllers). 958 | 959 | Give descriptive labels to views to make them easier to recognize, preferrably the same name as the referencing outlet if there is one. 960 | 961 | ![](http://f.cl.ly/items/3A2k2Z2m0n2t0b1L2V3n/Screen%20Shot%202013-06-05%20at%201.15.36%20PM.png) 962 | 963 | Golden Path 964 | =========== 965 | 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. 966 | 967 | Good: 968 | 969 | ```objc 970 | - (void)someMethod { 971 | if (![someOther boolValue]) return; 972 | //Do something important 973 | } 974 | ``` 975 | 976 | Bad: 977 | 978 | ```objc 979 | - (void)someMethod { 980 | if ([someOther boolValue]) {; 981 | //Do something important 982 | } 983 | } 984 | ``` 985 | 986 | More on Brackets 987 | ======== 988 | Method brackets should be at the end of the line, preceded by a single space 989 | 990 | Good: 991 | 992 | ```objc 993 | - (void)checkCondition { 994 | if (foo) { 995 | NSLog(@"Woof!"); 996 | } else { 997 | NSLog(@"Meow!"); 998 | } 999 | } 1000 | ``` 1001 | 1002 | Prevents Bugs: 1003 | 1004 | ```objc 1005 | if (foo) { 1006 | NSLog(@"Moof!"); 1007 | } 1008 | ``` 1009 | 1010 | Exception for Condition Checking: 1011 | 1012 | ```objc 1013 | if (condition) return; 1014 | ``` 1015 | 1016 | Note: Apple's templates sometimes have the opening bracket on a new line flush left, but generally at the end of the line. 1017 | 1018 | ```objc 1019 | - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 1020 | 1021 | static NSString *CellIdentifier = @"RootViewControllerCellIdentifier"; 1022 | .... 1023 | } 1024 | ``` 1025 | 1026 | Memory Management 1027 | ================= 1028 | If you're not using ARC you probably need to talk to the client about increasing the minimimum target OS version. 1029 | 1030 | Boyscout / Girl Guide 1031 | ===================== 1032 | Always leave the code in better condition than you found it. 1033 | 1034 | Copyrights 1035 | ===================== 1036 | By default, use a Robots & Pencils copyright. There may be special circumstances where it should be changed to a customer name. 1037 | 1038 | ```objc 1039 | // Copyright (c) 2012 Robots and Pencils Inc. All rights reserved. 1040 | ``` 1041 | 1042 | Set the Organization in your .xcodeproj to override your default company name for new files that are created. Select the project in File Navigator, then use the File Inspector (first button) in the Utilities pane. Set the organization to Robots and Pencils Inc. 1043 | 1044 | Proper Code Nutrition 1045 | ===================== 1046 | Avoid magic numbers with no meaning, preferring instead a named variable or constant (see following examples). 1047 | 1048 | Integers 1049 | -------- 1050 | Bad: 1051 | 1052 | ```objc 1053 | if ([pin length] < 5) 1054 | ``` 1055 | 1056 | What is this checking for? 1057 | 1058 | Good: 1059 | 1060 | ```objc 1061 | if ([pin length] > RBKPinSizeMax) 1062 | ``` 1063 | 1064 | We can see that this is checking if the pin is longer than the max allowed. 1065 | 1066 | Floats 1067 | ------ 1068 | In a (top level) .h you can define the float: 1069 | 1070 | ```objc 1071 | extern const float RBKFooFloat; 1072 | ``` 1073 | 1074 | and then in the relevant .m file assign it a value: 1075 | 1076 | ```objc 1077 | const float RBKFooFloat = 18.0; 1078 | ``` 1079 | 1080 | Strings 1081 | ------- 1082 | In a (top level) .h you can define the string: 1083 | 1084 | ```objc 1085 | extern NSString * const RBKLocationsDatabaseName; 1086 | ``` 1087 | 1088 | and then in the relevant .m file assign it a value: 1089 | 1090 | ```objc 1091 | NSString * const RBKLocationsDatabaseName = @"locations.db"; 1092 | ``` 1093 | 1094 | Note: the above is a constant pointer to an `NSString` object while the following is a pointer to a constant `NSString` object. 1095 | 1096 | Bad: 1097 | 1098 | ```objc 1099 | const NSString * RBKConstantString = @""; // pointer to constant 1100 | // which is equivalent to 1101 | NSString const * RBKConstantString = @""; 1102 | ``` 1103 | 1104 | Basic Code Principles 1105 | ------- 1106 | * Each function/method should aim to perform one action/task that reflects it's name. 1107 | * Since each function/method performs one action/task each one should be relatively short. If the code does not fit on one screen for example, you know you have a problem! 1108 | * Declare local variables as close to the code they are used in as possible. 1109 | * Always aim to reduce code nesting (ie a statement that is nested in an if, an if, a for and an if is hard for the brain to evaluate. Refactor!). 1110 | 1111 | Testing 1112 | ============ 1113 | * You are responsible for thoroughly testing your own code before passing off to quality assurance. 1114 | * Your code must always be tested by a minimum of one other person that is not you. 1115 | * Automated tests should always be added to at least critical code sections at a minimum (ex. algorithm to calculate mortgage details for a bank). 1116 | 1117 | Inspiration 1118 | ============ 1119 | 1120 | [Apple](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html#//apple_ref/doc/uid/10000146-SW1 "Apple") 1121 | 1122 | [Scott Stevenson](http://cocoadevcentral.com/articles/000082.php "Scott Stevenson") 1123 | 1124 | [Marcus Zarra](http://www.cimgf.com/zds-code-style-guide/ "Marcus Zarra") 1125 | 1126 | [Github](https://github.com/github/objective-c-conventions "Github") 1127 | 1128 | [NYTimes](https://github.com/NYTimes/objective-c-style-guide "NYTimes") 1129 | -------------------------------------------------------------------------------- /uncrustify.cfg: -------------------------------------------------------------------------------- 1 | # 2 | # Robots and Pencils Objective-C Style Guide 3 | # https://github.com/RobotsAndPencils/objective-c-style-guide 4 | # 5 | # File Created With UncrustifyX 0.4.3 (252) 6 | # 7 | 8 | # Alignment 9 | # --------- 10 | 11 | ## Alignment 12 | 13 | # Align ObjC declaration params on colon 14 | align_oc_decl_colon = true # boolean (false/true) 15 | 16 | # Align on tabstop 17 | align_on_tabstop = false # boolean (false/true) 18 | 19 | # Align variable definitions 20 | align_func_params = true # boolean (false/true) 21 | 22 | # Align with tabs 23 | align_with_tabs = false # boolean (false/true) 24 | 25 | # Keep non-indenting tabs 26 | align_keep_tabs = false # boolean (false/true) 27 | 28 | ## Alignment Span 29 | 30 | # Alignment span for #define bodies 31 | align_pp_define_span = 0 # number 32 | 33 | # Alignment span for ObjC message colons 34 | align_oc_msg_colon_span = 0 # number 35 | 36 | # Alignment span for ObjC message spec 37 | align_oc_msg_spec_span = 0 # number 38 | 39 | # Alignment span for equals in enums 40 | align_enum_equ_span = 0 # number 41 | 42 | # Alignment span for single-line typedefs 43 | align_typedef_span = 0 # number 44 | 45 | # Alignment span for struct initializer values 46 | align_struct_init_span = 0 # number 47 | 48 | # Alignment span for trailing comments 49 | align_right_cmt_span = 0 # number 50 | 51 | ## Alignment Style 52 | 53 | # Alignment style for star in variable definitions 54 | align_var_def_star_style = 1 # number 55 | 56 | ## Gap 57 | 58 | # Minimum gap between type and synonym of typedef 59 | align_typedef_gap = 0 # number 60 | 61 | # Minimum gap for trailing comment 62 | align_right_cmt_gap = 1 # number 63 | 64 | ## Other 65 | 66 | # Always align with first parameter in ObjC message 67 | align_oc_msg_colon_first = false # boolean (false/true) 68 | 69 | # Blank Lines 70 | # ----------- 71 | 72 | ## Newline Count After 73 | 74 | # Newline count after function body 75 | nl_after_func_body = 2 # number 76 | 77 | # Newline count after single-line function body 78 | nl_after_func_body_one_liner = 2 # number 79 | 80 | # Newline count after variable definition block 81 | nl_func_var_def_blk = 1 # number 82 | 83 | ## Other 84 | 85 | # Remove blank lines after open brace 86 | eat_blanks_after_open_brace = true # boolean (false/true) 87 | 88 | # Remove blank lines before close brace 89 | eat_blanks_before_close_brace = true # boolean (false/true) 90 | 91 | # Code-Modifying 92 | # -------------- 93 | 94 | ## Braces 95 | 96 | # Braces around statments that span N newlines 97 | mod_full_brace_nl = 2 # number 98 | 99 | # Braces on single-line do statement 100 | mod_full_brace_do = ignore # string (add/force/ignore/remove) 101 | 102 | # Braces on single-line else statement 103 | mod_full_brace_if = force # string (add/force/ignore/remove) 104 | 105 | # Braces on single-line for statement 106 | mod_full_brace_for = force # string (add/force/ignore/remove) 107 | 108 | # Braces on single-line while statement 109 | mod_full_brace_while = force # string (add/force/ignore/remove) 110 | 111 | ## Comments 112 | 113 | # Add comment after ifdef/else statement of size 114 | mod_add_long_ifdef_else_comment = 20 # number 115 | 116 | # Add comment after ifdef/endif statement of size 117 | mod_add_long_ifdef_endif_comment = 20 # number 118 | 119 | ## Parentheses 120 | 121 | # Remove unnecessary parentheses on return statement 122 | mod_paren_on_return = remove # string (add/force/ignore/remove) 123 | 124 | ## Semicolons 125 | 126 | # Remove superflous semicolons 127 | mod_remove_extra_semicolon = false # boolean (false/true) 128 | 129 | # Comments 130 | # -------- 131 | 132 | ## Empty Lines 133 | 134 | # Empty first line for multi-line C comments 135 | cmt_c_nl_start = true # boolean (false/true) 136 | 137 | # Empty first line for multi-line C++ comments 138 | cmt_cpp_nl_start = true # boolean (false/true) 139 | 140 | ## Other 141 | 142 | # Stars on multi-line comments 143 | cmt_star_cont = true # boolean (false/true) 144 | 145 | # General 146 | # ------- 147 | 148 | ## Other 149 | 150 | # Newline character 151 | newlines = lf # string (auto/cr/crlf/lf) 152 | 153 | # Output tab size 154 | output_tab_size = 4 # number 155 | 156 | # Indentation 157 | # ----------- 158 | 159 | ## Indentation 160 | 161 | # Indent ObjC block 162 | indent_oc_block = true # boolean (false/true) 163 | 164 | ## Indentation Size 165 | 166 | # Indentation column size 167 | indent_columns = 4 # number 168 | 169 | # Indentation size between case and switch 170 | indent_switch_case = 4 # number 171 | 172 | # Indentation size for ObjC blocks in a message parameter 173 | indent_oc_block_msg = 0 # number 174 | 175 | # Indentation size for ObjC message subsequent parameters 176 | indent_oc_msg_colon = 4 # number 177 | 178 | ## Other 179 | 180 | # Align continued statements at equals 181 | indent_align_assign = false # boolean (false/true) 182 | 183 | # Indent goto labels 184 | indent_label = 4 # number 185 | 186 | # Indent with tabs 187 | indent_with_tabs = 0 # number 188 | 189 | # Newlines 190 | # -------- 191 | 192 | ## Merging 193 | 194 | # Change unbraced if statements into one-liner 195 | nl_create_if_one_liner = true # boolean (false/true) 196 | 197 | ## Newline After 198 | 199 | # Newline after brace open 200 | nl_after_brace_open = true # boolean (false/true) 201 | 202 | # Newline after for 203 | nl_after_for = force # string (add/force/ignore/remove) 204 | 205 | # Newline after if 206 | nl_after_if = force # string (add/force/ignore/remove) 207 | 208 | # Newline after macro multi-line definition 209 | nl_multi_line_define = true # boolean (false/true) 210 | 211 | # Newline after return 212 | nl_after_return = true # boolean (false/true) 213 | 214 | ## Newline Before 215 | 216 | # Newline before case statement 217 | nl_before_case = true # boolean (false/true) 218 | 219 | # Newline before for 220 | nl_before_for = ignore # string (add/force/ignore/remove) 221 | 222 | # Newline before if 223 | nl_before_if = ignore # string (add/force/ignore/remove) 224 | 225 | # Newline before while 226 | nl_before_while = ignore # string (add/force/ignore/remove) 227 | 228 | ## Newline Between 229 | 230 | # Newline between case colon and open brace 231 | nl_case_colon_brace = remove # string (add/force/ignore/remove) 232 | 233 | # Newline between catch and open brace 234 | nl_catch_brace = remove # string (add/force/ignore/remove) 235 | 236 | # Newline between close brace and catch 237 | nl_brace_catch = remove # string (add/force/ignore/remove) 238 | 239 | # Newline between close brace and else 240 | nl_brace_else = force # string (add/force/ignore/remove) 241 | 242 | # Newline between close brace and finally 243 | nl_brace_finally = remove # string (add/force/ignore/remove) 244 | 245 | # Newline between close brace and while 246 | nl_brace_while = remove # string (add/force/ignore/remove) 247 | 248 | # Newline between close parenthesis and open brace in multi line conditional 249 | nl_multi_line_cond = false # boolean (false/true) 250 | 251 | # Newline between do and open brace 252 | nl_do_brace = remove # string (add/force/ignore/remove) 253 | 254 | # Newline between else and open brace 255 | nl_else_brace = remove # string (add/force/ignore/remove) 256 | 257 | # Newline between else if and open brace 258 | nl_elseif_brace = remove # string (add/force/ignore/remove) 259 | 260 | # Newline between enum and open brace 261 | nl_enum_brace = remove # string (add/force/ignore/remove) 262 | 263 | # Newline between finally and open brace 264 | nl_finally_brace = remove # string (add/force/ignore/remove) 265 | 266 | # Newline between for and open brace 267 | nl_for_brace = remove # string (add/force/ignore/remove) 268 | 269 | # Newline between function call and open brace 270 | nl_fcall_brace = remove # string (add/force/ignore/remove) 271 | 272 | # Newline between function signature and open brace 273 | nl_fdef_brace = remove # string (add/force/ignore/remove) 274 | 275 | # Newline between if and open brace 276 | nl_if_brace = remove # string (add/force/ignore/remove) 277 | 278 | # Newline between struct and open brace 279 | nl_struct_brace = remove # string (add/force/ignore/remove) 280 | 281 | # Newline between switch and open brace 282 | nl_switch_brace = remove # string (add/force/ignore/remove) 283 | 284 | # Newline between try and open brace 285 | nl_try_brace = remove # string (add/force/ignore/remove) 286 | 287 | # Newline between union and open brace 288 | nl_union_brace = remove # string (add/force/ignore/remove) 289 | 290 | # Newline between while and open brace 291 | nl_while_brace = remove # string (add/force/ignore/remove) 292 | 293 | ## Other 294 | 295 | # Don't split one-line ObjC messages 296 | nl_oc_msg_leave_one_liner = true # boolean (false/true) 297 | 298 | # Newlines at end of file 299 | nl_end_of_file = force # string (add/force/ignore/remove) 300 | nl_end_of_file_min = 1 301 | 302 | # Place ObjC message parameters on new lines 303 | nl_oc_msg_args = false # boolean (false/true) 304 | 305 | # Spacing 306 | # ------- 307 | 308 | ## Space After 309 | 310 | # Space after C++ comment opening 311 | sp_cmt_cpp_start = ignore # string (add/force/ignore/remove) 312 | 313 | # Space after ObjC block caret 314 | sp_after_oc_block_caret = remove # string (add/force/ignore/remove) 315 | 316 | # Space after ObjC colon 317 | sp_after_oc_colon = remove # string (add/force/ignore/remove) 318 | 319 | # Space after ObjC dictionary colon 320 | sp_after_oc_dict_colon = add # string (add/force/ignore/remove) 321 | 322 | # Space after ObjC message colon 323 | sp_after_send_oc_colon = remove # string (add/force/ignore/remove) 324 | 325 | # Space after ObjC property 326 | sp_after_oc_property = add # string (add/force/ignore/remove) 327 | 328 | # Space after ObjC return type 329 | sp_after_oc_return_type = remove # string (add/force/ignore/remove) 330 | 331 | # Space after ObjC scope 332 | sp_after_oc_scope = force # string (add/force/ignore/remove) 333 | 334 | # Space after ObjC type 335 | sp_after_oc_type = remove # string (add/force/ignore/remove) 336 | 337 | # Space after cast 338 | sp_after_cast = remove # string (add/force/ignore/remove) 339 | 340 | # Space after class colon 341 | sp_after_class_colon = force # string (add/force/ignore/remove) 342 | 343 | # Space after comma 344 | sp_after_comma = add # string (add/force/ignore/remove) 345 | 346 | # Space after condition close parenthesis 347 | sp_after_sparen = force # string (add/force/ignore/remove) 348 | 349 | # Space after pointer star 350 | sp_after_ptr_star = remove # string (add/force/ignore/remove) 351 | 352 | # Space after pointer star followed by function 353 | sp_after_ptr_star_func = force # string (add/force/ignore/remove) 354 | 355 | ## Space Around 356 | 357 | # Space around arithmetic operators 358 | sp_arith = add # string (add/force/ignore/remove) 359 | 360 | # Space around assignment operator 361 | sp_assign = add # string (add/force/ignore/remove) 362 | 363 | # Space around boolean operators 364 | sp_bool = add # string (add/force/ignore/remove) 365 | 366 | # Space around compare operators 367 | sp_compare = add # string (add/force/ignore/remove) 368 | 369 | # Space around ternary condition colon 370 | sp_cond_colon = force # string (add/force/ignore/remove) 371 | 372 | # Space around ternary condition question mark 373 | sp_cond_question = force # string (add/force/ignore/remove) 374 | 375 | ## Space Before 376 | 377 | # Space before ObjC block caret 378 | sp_before_oc_block_caret = ignore # string (add/force/ignore/remove) 379 | 380 | # Space before ObjC colon 381 | sp_before_oc_colon = remove # string (add/force/ignore/remove) 382 | 383 | # Space before ObjC dictionary colon 384 | sp_before_oc_dict_colon = force # string (add/force/ignore/remove) 385 | 386 | # Space before ObjC message colon 387 | sp_before_send_oc_colon = remove # string (add/force/ignore/remove) 388 | 389 | # Space before case colon 390 | sp_before_case_colon = remove # string (add/force/ignore/remove) 391 | 392 | # Space before class colon 393 | sp_before_class_colon = force # string (add/force/ignore/remove) 394 | 395 | # Space before if/for/switch/while open parenthesis 396 | sp_before_sparen = force # string (add/force/ignore/remove) 397 | 398 | # Space before pointer star 399 | sp_before_ptr_star = force # string (add/force/ignore/remove) 400 | 401 | # Space before pointer star followed by function 402 | sp_before_ptr_star_func = force # string (add/force/ignore/remove) 403 | 404 | # Space before unnamed pointer star 405 | sp_before_unnamed_ptr_star = ignore # string (add/force/ignore/remove) 406 | 407 | ## Space Between 408 | 409 | # Space between @selector and open parenthesis 410 | sp_after_oc_at_sel = remove # string (add/force/ignore/remove) 411 | 412 | # Space between catch and open brace 413 | sp_catch_brace = add # string (add/force/ignore/remove) 414 | 415 | # Space between catch and open parenthesis 416 | sp_catch_paren = add # string (add/force/ignore/remove) 417 | 418 | # Space between close brace and else 419 | sp_brace_else = force # string (add/force/ignore/remove) 420 | 421 | # Space between close parenthesis and open brace 422 | sp_paren_brace = force # string (add/force/ignore/remove) 423 | 424 | # Space between closing brace and catch 425 | sp_brace_catch = add # string (add/force/ignore/remove) 426 | 427 | # Space between closing brace and finally 428 | sp_brace_finally = add # string (add/force/ignore/remove) 429 | 430 | # Space between closing parenthesis and open brace 431 | sp_fparen_brace = force # string (add/force/ignore/remove) 432 | 433 | # Space between else and open brace 434 | sp_else_brace = force # string (add/force/ignore/remove) 435 | 436 | # Space between finally and open brace 437 | sp_finally_brace = add # string (add/force/ignore/remove) 438 | 439 | # Space between function name and open parenthesis 440 | sp_func_call_paren = remove # string (add/force/ignore/remove) 441 | 442 | # Space between function name and open parenthesis in declaration 443 | sp_func_proto_paren = remove # string (add/force/ignore/remove) 444 | 445 | # Space between function name and open parenthesis in function definition 446 | sp_func_def_paren = remove # string (add/force/ignore/remove) 447 | 448 | # Space between pointer stars 449 | sp_between_ptr_star = remove # string (add/force/ignore/remove) 450 | 451 | # Space between sizeof and open parenthesis 452 | sp_sizeof_paren = remove # string (add/force/ignore/remove) 453 | 454 | # Space between try and open brace 455 | sp_try_brace = add # string (add/force/ignore/remove) 456 | 457 | ## Space Inside 458 | 459 | # Space inside @selector() parens 460 | sp_inside_oc_at_sel_parens = remove # string (add/force/ignore/remove) 461 | 462 | # Space inside braces 463 | sp_inside_braces = add # string (add/force/ignore/remove) 464 | 465 | # Space inside cast parentheses 466 | sp_inside_paren_cast = remove # string (add/force/ignore/remove) 467 | 468 | # Space inside enum braces 469 | sp_inside_braces_enum = add # string (add/force/ignore/remove) 470 | 471 | # Space inside function parentheses 472 | sp_inside_fparen = remove # string (add/force/ignore/remove) 473 | 474 | # Space inside if-condition parentheses 475 | sp_inside_sparen = remove # string (add/force/ignore/remove) 476 | 477 | # Space inside parentheses 478 | sp_inside_paren = remove # string (add/force/ignore/remove) 479 | 480 | # Space inside parentheses in function type 481 | sp_inside_tparen = remove # string (add/force/ignore/remove) 482 | 483 | # Space inside struct/union braces 484 | sp_inside_braces_struct = add # string (add/force/ignore/remove) 485 | --------------------------------------------------------------------------------