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

Block

Khoa Pham
August 27, 2015

 Block

How block works

Khoa Pham

August 27, 2015
Tweet

More Decks by Khoa Pham

Other Decks in Programming

Transcript

  1. Block
    Khoa Pham - 2359Media

    View Slide

  2. Block
    Definition
    Syntax
    Capture
    Usage

    View Slide

  3. Definition

    View Slide

  4. Block
    The closure that Apple adds to C
    Is an object (NSBlock)
    The compiler translate block literals into struct
    and functions. So we don’t see the alloc call

    View Slide

  5. Block
    It is said to be the only object that can be
    allocated on the stack, by default.
    It is moved to heap when copied.

    View Slide

  6. Block
    struct + captured state information

    View Slide

  7. Syntax

    View Slide

  8. Syntax
    The syntax of Objective C block http://arigrant.
    com/blog/2014/1/18/the-syntax-of-objective-c-blocks
    From C declarators to Objective C block syntax
    http://nilsou.com/blog/2013/08/21/objective-c-blocks-syntax/
    Cheatsheet
    http://fuckingblocksyntax.com/

    View Slide

  9. Syntax
    *
    []
    ()
    ^

    View Slide

  10. Syntax
    () > [] > *, ^
    Start from the variable name to right
    Then to the left
    Operator precedence http://unixwiz.net/techtips/reading-cdecl.html
    CDECL http://cdecl.org/

    View Slide

  11. Syntax
    int a;

    View Slide

  12. Syntax
    int a;
    a is an int

    View Slide

  13. Syntax
    int *a;

    View Slide

  14. Syntax
    int *a;
    a is a pointer to an int

    View Slide

  15. Syntax
    int a[];

    View Slide

  16. Syntax
    int a[];
    a is an array of int

    View Slide

  17. Syntax
    int f();

    View Slide

  18. Syntax
    int f();
    f is a function that returns an int

    View Slide

  19. Syntax
    int f(long);
    f is a function that returns an int, and accepts a
    long

    View Slide

  20. Syntax
    int *a[];

    View Slide

  21. Syntax
    int *a[];
    a is an array of pointers to int

    View Slide

  22. Syntax
    int *(a[]);
    a is an array of pointers to int

    View Slide

  23. Syntax
    int (*)a[];

    View Slide

  24. Syntax
    int (*)a[];
    a is a pointer to an array of ints

    View Slide

  25. Syntax
    int *f();

    View Slide

  26. Syntax
    int *f();
    f is function that returns a pointer to an int

    View Slide

  27. Syntax
    int *(f());
    f is function that returns a pointer to an int

    View Slide

  28. Syntax
    int (*f)();

    View Slide

  29. Syntax
    int (*f)();
    f is a pointer to a function which accepts
    nothing and returns an int

    View Slide

  30. Syntax
    void (^successBlock)(NSDictionary
    *response);
    successBlock is a block pointer to a function
    which takes a dictionary and returns nothing

    View Slide

  31. Syntax
    ^ is the block pointer, which can only be
    applied to function
    int ^f(); // Error

    View Slide

  32. ^ unary operator
    int (^doubleMe)(int) = ^(int a){
    return a * 2;
    }
    int b = doubleMe(2);

    View Slide

  33. ^ unary operator
    Transform function implementation into a
    block
    Infer the return type

    View Slide

  34. ^ unary operator
    BOOL (^customBlock)(NSArray *) = ^(NSArray *array) {
    // return array.count == 3; // Please don’t
    if (array.count == 3) {
    return YES;
    }
    return NO;
    };

    View Slide

  35. __block
    What does the block keyword mean
    http://stackoverflow.com/questions/7080927/what-does-the-block-keyword-
    mean

    View Slide

  36. __block
    Access to __block variable
    http://clang.llvm.org/docs/Block-ABI-Apple.html#layout-of-block-marked-
    variables
    By default, variables used withtin the block are
    copied
    Rewrite access,

    View Slide

  37. __block (Kiwi example)
    describe(@"it takes a while"
    , ^{
    __block NSDictionary *apiResponse = nil;
    beforeAll(^{
    __block BOOL requestCompleted = NO;
    AFJSONRequestOperation *operation = [AFJSONRequestOperation
    JSONRequestOperationWithRequest:
    request
    success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    requestCompleted = YES;
    apiResponse = JSON;
    }
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
    requestCompleted = YES;
    }
    ];
    [operation start];
    [KWSpec waitWithTimeout:3.0 forCondition:
    ^BOOL() {
    return requestCompleted;
    }];
    });
    it(@"includes the related objects in the response"
    , ^{
    [[[apiResponse objectForKey:
    @"children"
    ] should] containObjects:
    @"foo", @"bar", @"baz", nil];
    });
    });

    View Slide

  38. Capture

    View Slide

  39. Capture
    The ability to capture values from the enclosing
    scope, making them similar to closures or
    lambdas in other programming languages.

    View Slide

  40. weakSelf vs strongSelf
    __weak __typeof__(self) weakSelf = self;
    self.block = ^{
    __typeof__(self) strongSelf = weakSelf;
    [strongSelf doSomething];
    [strongSelf doSomethingElse];
    };
    The block property is declared as “copy”

    View Slide

  41. weakSelf vs strongSelf
    Understand weakSelf and strongSelf
    http://www.fantageek.
    com/1090/understanding-weak-self-and-
    strong-self/

    View Slide

  42. weakSelf vs strongSelf
    Block is allocated on the stack. It has no effect
    on the storage of lifetime of anything it
    accesses.
    When they are copied, they take their captured
    scope with them, retaining any objects they
    refer

    View Slide

  43. weakSelf vs strongSelf
    Block captures the variable along with its
    decorators (i.e. weak qualifier),

    View Slide

  44. weakSelf vs strongSelf
    Block captures the variable along with its
    decorators (i.e. weak qualifier),

    View Slide

  45. weakSelf vs strongSelf
    You should only use a weak reference to self, if
    self will hold on to a reference of the block.

    View Slide

  46. Take care

    View Slide

  47. UIView animation block
    [UIView animateWithDuration:0.5
    delay:1.0
    options: UIViewAnimationCurveEaseOut
    animations:^{
    self.basketTop.frame = basketTopFrame;
    self.basketBottom.frame = basketBottomFrame;
    }
    completion:^(BOOL finished){
    NSLog(@"Done!");
    }];

    View Slide

  48. UIView animation block
    - (void)loopThisBlock
    {
    [UIView animateWithDuration:0.2 animations:^{
    someView.alpha = (someView.alpha + 1.0) % 2;
    } completion:^(BOOL finished) {
    [self loopThisBlock];
    }];
    }
    What if the block is executed infinitely ?

    View Slide

  49. AFNetworking callback block
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager
    manager];
    [manager GET:@"http://example.com/resources.json" parameters:nil success:^
    (AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
    }];

    View Slide

  50. Notification handler block
    [[NSNotificationCenter defaultCenter]
    addObserverForNotificationName:@"NotificationName"
    object:nil
    queue:[NSOperationQueue mainQueue]
    block:^(NSNotification *notification) {
    //reload the table to show the new whiz bangs
    NSAssert(notification, @"Notification must not be nil");
    [self.tableView reloadData];
    }];

    View Slide

  51. Usage

    View Slide

  52. DSL
    Masonry
    Kiwi
    FTGValidator

    View Slide

  53. DSL
    REQUIRE_STRING(@"90001").to.matchRegExWithPattern(@"^[0-9][0-9][0-9][0-9][0-
    9]$").with.message(@"Value must be US zip code format"),
    [view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.edges.equalTo(superview).with.insets(padding);
    }];

    View Slide

  54. DSL
    - (FTGStringRule * (^)(NSString *anotherValue))equalTo {
    return ^(NSString *anotherValue){
    [self setValidation:^BOOL(NSString *value) {
    return [value isEqualToString:anotherValue];
    }];
    return self;
    };
    }

    View Slide

  55. Syntactic sugar
    https://github.com/supermarin/ObjectiveSugar
    [@3 times:^{
    NSLog(@"Hello!");
    }];
    [cars each:^(id object) {
    NSLog(@"Car: %@", object);
    }];

    View Slide

  56. Syntactic sugar
    https://github.com/supermarin/ObjectiveSugar
    [@3 times:^{
    NSLog(@"Hello!");
    }];
    [cars each:^(id object) {
    NSLog(@"Car: %@", object);
    }];

    View Slide

  57. Condition
    http://blog.vikingosegundo.de/2012/10/05/pattern-switch-value-object/
    NSArray *filter = @[caseYES, caseNO];
    id obj1 = @"YES";
    id obj2 = @"NO";
    [obj1 processByPerformingFilterBlocks:filter];
    [obj2 processByPerformingFilterBlocks:filter];

    View Slide

  58. Mapping with block
    http://www.merowing.info/2014/03/refactoring-tricks/#.VNw2IlOUc8Y
    NSString *(^const format)(NSUInteger, NSString *, NSString *) = ^(NSUInteger value, NSString
    *singular, NSString *plural) {
    return [NSString stringWithFormat:@"%d %@", value, (value == 1 ? singular : plural)];
    };

    View Slide

  59. Reference
    1. http://www.galloway.me.uk/2012/10/a-look-inside-blocks-episode-1/
    2. https://blackpixel.com/writing/2014/03/capturing-myself.html
    3. http://albertodebortoli.github.io/blog/2013/04/21/objective-c-blocks-
    under-the-hood/
    4. http://stackoverflow.com/questions/20134616/how-are-nsblock-objects-
    created
    5. http://nilsou.com/blog/2013/08/21/objective-c-blocks-syntax/
    6. http://clang.llvm.org/docs/Block-ABI-Apple.html#blocks-as-objects
    7. http://albertodebortoli.github.io/blog/2013/08/03/objective-c-blocks-
    caveat/

    View Slide

  60. Thanks

    View Slide