Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Objective-C Sins

Objective-C Sins

I have a confession to make. I've written some terrible Objective-C code. I guess you can say I've sinned. In this talk, I discuss common anti-patterns and how to avoid them.

This talk was originally presented to students of the iOS class at The Flatiron School. Without the actual talking to go with it, these slides are probably missing a lot of context. If you're confused about something, send me a message on twitter (@mb).

Matthew Bischoff

October 29, 2013
Tweet

More Decks by Matthew Bischoff

Other Decks in Technology

Transcript

  1. View Slide

  2. Objective-C Sins

    View Slide

  3. sin 1 |sin|
    noun
    an immoral act considered to be a transgression against
    divine law: a sin in the eyes of God | the human capacity for sin.
    !
    • an act regarded as a serious or regrettable fault, offense, or
    omission: he committed the unforgivable sin of refusing to give
    interviews | humorous : with air like this, it's a sin not to go out.

    View Slide

  4. sin 1 |sin|
    noun
    an immoral act considered to be a transgression against
    divine law: a sin in the eyes of God | the human capacity for sin.
    !
    • an act regarded as a serious or regrettable fault, offense, or
    omission: he committed the unforgivable sin of refusing to give
    interviews | humorous : with air like this, it's a sin not to go out.

    View Slide

  5. @mb

    View Slide

  6. matthew bischoff

    View Slide

  7. matt

    View Slide

  8. View Slide

  9. Velocity
    Quotebook

    View Slide

  10. View Slide

  11. View Slide

  12. Sins

    View Slide

  13. [object retainCount];

    View Slide

  14. View Slide

  15. Why not?

    View Slide

  16. Object retainCount? Actual retainCount
    [NSNumber numberWithInt:1] 1 2
    @"Matt" 1 1152921504606846975
    [NSString stringWithString:@"Matt"] 1 1152921504606846975

    View Slide

  17. Key-Value Observing

    View Slide

  18. Key-Value Observing has the
    worst API in all of Cocoa. It’s
    awkward, verbose, and confusing.
    Mattt Thompson

    View Slide

  19. “Stringly Typed”

    View Slide

  20. Refactoring is scary.

    View Slide

  21. Throws Exceptions

    View Slide

  22. ARC == garbage collection

    View Slide

  23. You still have to pay attention.

    View Slide

  24. . Syntax
    [ ] Syntax

    View Slide

  25. What’s the obvious thing to do, the easiest
    way to agree? Just do what the headers say. If
    it’s a property, treat it as such. If it’s not, don’t.
    !
    And when in doubt, look it up.
    Brent Simmons

    View Slide

  26. Dot syntax is for properties.

    View Slide

  27. Bracket syntax is for methods.

    View Slide

  28. UIColor.clearColor;
    array.count;
    object.hash;

    View Slide

  29. More than 1 Class per file

    View Slide

  30. View Slide

  31. performSelector:
    afterDelay:

    View Slide

  32. It’s a crash waiting to happen.

    View Slide

  33. Missing or improper reuse

    View Slide

  34. Always reuse cells.

    View Slide

  35. Don’t keep track of cells.

    View Slide

  36. Architecture-dependent
    primitive types

    View Slide

  37. int
    float
    double

    View Slide

  38. NSInteger / NSUInteger
    CGFloat
    NSTimeInterval

    View Slide

  39. Violating MVC

    View Slide

  40. Models that do networking

    View Slide

  41. Views that know about models

    View Slide

  42. Controllers that do layout

    View Slide

  43. NSDictionary

    View Slide

  44. Not a replacement for a model

    View Slide

  45. ✨"

    View Slide

  46. Magic numbers

    View Slide

  47. Repeating yourself
    Repeating yourself
    Repeating yourself
    Repeating yourself
    Repeating yourself
    Repeating yourself

    View Slide

  48. Every piece of knowledge must
    have a single, unambiguous,
    authoritative representation
    within a system.
    Andy Hunt and Dave Thomas

    View Slide

  49. if (taylorSwift) {
    taylorSwift.age = 22;
    }

    View Slide

  50. id

    View Slide

  51. Singletons

    View Slide

  52. Blocking the main queue

    View Slide

  53. Low level APIs

    View Slide

  54. CoreFoundation
    CoreText
    CoreGraphics
    CoreAnimation

    View Slide

  55. Foundation
    TextKit
    UIKit
    UIView Animations

    View Slide

  56. @property (nonatomic, strong, readwrite) NSString *title;

    View Slide

  57. @property (nonatomic) NSString *title;

    View Slide

  58. @property NSString *title;

    View Slide

  59. Warnings

    View Slide

  60. Unused Variable ‘sin’
    !

    View Slide

  61. Unused Variable ‘sin’
    !

    View Slide

  62. Public and readwrite

    View Slide

  63. Missing #pragma marks

    View Slide

  64. #pragma mark - NSObject
    !
    - (void)dealloc {}
    !
    #pragma mark - UIViewController
    !
    - (void)viewDidLoad {}
    !
    #pragma mark - LCKDocumentsTableViewController
    !
    - (void)setupRefreshControl {}

    View Slide

  65. Bad names

    View Slide

  66. UIImage *img;
    UIButton *btn;
    NSString *str;
    NSArray *arr;
    NSDictionary *dict;
    NSInteger i;

    View Slide

  67. UIImage *avatar;
    UIButton *signupButton;
    NSString *name;
    NSArray *people;
    NSDictionary *userInfo;
    NSInteger count;

    View Slide

  68. Two-letter prefixes

    View Slide

  69. NS
    UI
    CG
    CA
    AC
    ST
    XC
    SK
    MF
    AD

    View Slide

  70. Two-letter prefixes…are reserved by
    Apple for use in framework classes.
    !
    Your own classes should use three
    letter prefixes.

    View Slide

  71. Inconsistent style

    View Slide

  72. View Slide

  73. Not overriding the
    designated initializer

    View Slide

  74. - (instancetype)initWithPerson:(LCKPerson *)person {
    self = [super initWithStyle:UITableViewStylePlain];
    if (self) {
    _person = person;
    _dataStore = [NSMutableDictionary dictionary];
    }
    return self;
    }

    View Slide

  75. - (id)initWithStyle:(UITableViewStyle)style {
    return [self initWithPerson:nil];
    }
    !
    - (instancetype)initWithPerson:(LCKPerson *)person {
    self = [super initWithStyle:UITableViewStylePlain];
    if (self) {
    _person = person;
    _dataStore = [NSMutableDictionary dictionary];
    }
    return self;
    }

    View Slide

  76. UITapGestureRecognizer

    View Slide

  77. Just use a UIButton.

    View Slide

  78. UISwipeGestureRecognizer

    View Slide

  79. Just use a UIPanGestureRecognizer.

    View Slide

  80. Inaccessibility

    View Slide

  81. View Slide

  82. Property Description Example
    accessibilityLabel
    Identifies the accessibility element, but does not include the
    type of the control or view
    “Share”
    accessibilityValue
    The value is a localized string that contains the current value
    of an element
    “35 %”
    accessibilityHint
    Description of the result of performing an action on the
    element.
    “Selects the
    message”

    View Slide

  83. Missing Localization

    View Slide

  84. View Slide

  85. // Unnecessary comments

    View Slide

  86. Comments explain why.
    Not what or how.

    View Slide

  87. true && false

    View Slide

  88. YES and and NO

    View Slide

  89. Profiling at the end

    View Slide

  90. View Slide

  91. [[[[[too much] code] on] one] line]

    View Slide

  92. #import

    View Slide

  93. #define

    View Slide

  94. retain cycles

    View Slide

  95. Object Object
    strong

    View Slide

  96. [self.queue addOperationWithBlock:^{
    [self download];
    }];

    View Slide

  97. __weak typeof(self) weakSelf = self;
    [self.queue addOperationWithBlock:^{
    [weakSelf download];
    }];

    View Slide

  98. (assign) delegates

    View Slide

  99. self.webView.delegate = nil;

    View Slide

  100. Blended layers

    View Slide

  101. View Slide

  102. View Slide

  103. Mixing up nothing

    View Slide

  104. nil, Nil, NULL, NSNull

    View Slide

  105. Symbol Value Meaning
    NULL (void *)0 literal null value for C pointers
    nil (id)0 literal null value for Objective-C objects
    Nil (Class)0 literal null value for Objective-C classes
    NSNull [NSNull null] singleton object used to represent null

    View Slide

  106. Ignoring crash logs

    View Slide

  107. View Slide

  108. Special Thanks
    •Ash Furrow
    •Brent Simmons
    •Mattt Thompson
    •Brian Capps

    View Slide

  109. Thank you.

    View Slide

  110. Questions?

    View Slide