Skip to content
Blocks
step 1/4

Reading — step 1 of 4

Learn

~1 min readBlocks and Errors

Blocks are Objective-C's closures — anonymous functions you can pass around.

Syntax: ^returnType (args) { body }. Often inferred:

// Type: int (^)(int)
int (^square)(int) = ^(int n) {
    return n * n;
};

NSLog(@"%d", square(5));    // 25

The caret ^ marks both the type and the literal.

Capturing variables — blocks close over local scope, copying by value:

int base = 100;
int (^add)(int) = ^(int n) {
    return n + base;        // base is captured
};
base = 200;                 // doesn't affect the block (already captured)
NSLog(@"%d", add(5));        // 105 — block sees base=100

For mutable captures, use __block:

__block int counter = 0;
void (^increment)(void) = ^{ counter++; };
increment();
increment();
NSLog(@"%d", counter);       // 2 — counter is shared

Common use cases:

  • Iteration callbacks: [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { ... }]
  • Completion handlers: [downloader fetchWithCompletion:^(NSData *data, NSError *err) { ... }]
  • Sorting: [array sortedArrayUsingComparator:^NSComparisonResult(id a, id b) { ... }]

Memory caveats — blocks are objects. ARC manages them, but capturing self strongly inside an instance method's block can create retain cycles:

// Cycle: self -> block -> self
[self.api fetch:^(id result) { self.value = result; }];

// Fix with weak reference:
__weak typeof(self) weakSelf = self;
[self.api fetch:^(id result) { weakSelf.value = result; }];

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…