ios development with blocks

50
iOS Development with Blocks Jeff Kelley (@jeff_r_kelley) MobiDevDay Detroit | February 19, 2011 Slides will be on blog.slaunchaman.com

Upload: jeff-kelley

Post on 22-Jun-2015

5.875 views

Category:

Technology


0 download

DESCRIPTION

Slides from Jeff Kelley’s MobiDevDay presentation on blocks and iOS.

TRANSCRIPT

Page 1: iOS Development with Blocks

iOS Development with Blocks

Jeff Kelley (@jeff_r_kelley)MobiDevDay Detroit | February 19, 2011

Slides will be on blog.slaunchaman.com

Page 2: iOS Development with Blocks

Introduction

• Blocks

• What are blocks?

• Why should we use blocks?

• Grand Central Dispatch

• How does GCD help iOS development?

Page 3: iOS Development with Blocks

Blocks

• Apple extension to the C language

• Similar to closures, lambdas, etc.

• Encapsulate code like a function, but with extra “magic”

Page 4: iOS Development with Blocks

Your First Block

void (^helloWorldBlock)(void) = ^ {

printf ("Hello, World!\n");

};

Page 5: iOS Development with Blocks

Calling Your First Block

void (^helloWorldBlock)(void) = ^ {

printf ("Hello, World!\n");

};

helloWorldBlock();

Page 6: iOS Development with Blocks

Blocks That Return

• Blocks return just like functions.

int (^fortyTwo)(void) = ^{

return 42;

}

int a = fortyTwo();

Page 7: iOS Development with Blocks

Blocks That Take Arguments

• Just like functions:

BOOL (^isFortyTwo)(int) = ^(int a) {

return (a == 42);

}

BOOL myBool = isFortyTwo(5); // NO

Page 8: iOS Development with Blocks

Blocks Capture Scope

int a = 42;

void (^myBlock)(void) = ^{

printf("a = %d\n", a);

};

myBlock();

Page 9: iOS Development with Blocks

int a = 42;

void (^myBlock)(void) = ^{

a++;

printf("a = %d\n", a);

};

myBlock();

Page 10: iOS Development with Blocks

__block int a = 42;

void (^myBlock)(void) = ^{

a++;

printf("a = %d\n", a);

};

myBlock();

Page 11: iOS Development with Blocks

Block Typedefs

• Simple block that returns an int and takes a float:

typedef int (^floatToIntBlock)(float);

• Now initialize it:

floatToIntBlock foo = ^(float a) { return (int)a;};

Page 12: iOS Development with Blocks

Using Blocks as Arguments

• Method Signature:

• - (void)doThisBlock:(void (^)(id obj))block

• returns void, takes id argument

Page 13: iOS Development with Blocks

Block Typedefs As Arguments

• First typedef the block, then use it as an argument:

typedef int (^floatToIntBlock)(float);

void useMyBlock(floatToIntBlock foo);

Page 14: iOS Development with Blocks

Block Scope

void (^myBlock)(void);

if (someValue == YES) {

myBlock = ^{ printf("YES!\n") };

} else {

myBlock = ^ { printf("NO!\n") };

}

Page 15: iOS Development with Blocks

Block Memory Management

• Block_copy() and Block_release()

• Copied onto heap

• Blocks are Objective-C objects!

• [myBlock copy];

• [myBlock release];

Page 16: iOS Development with Blocks

Block Memory Management

• Unlike Objective-C objects, blocks are created on the stack

• Block_copy() moves them to the heap

• Block_retain() does not.

• Can also call [myBlock autorelease]

Page 17: iOS Development with Blocks

NSString *helloWorld = [[NSString alloc] initWithString:@"Hello, World!"];

void (^helloBlock)(void) = ^{

NSLog(@"%@", helloWorld);

};

[helloWorld release];

helloBlock();

Blocks Retain Objects

Page 18: iOS Development with Blocks

What Are Blocks Good For?

• Replacing Callbacks

• Notification Handlers

• Enumeration

Page 19: iOS Development with Blocks

What Are Blocks Good For?

• Replacing Callbacks

• Notification Handlers

• Enumeration

Page 20: iOS Development with Blocks

Replacing Callbacks

• Old UIView animations:

[UIView beginAnimations:@"foo" context:nil];

[UIView setAnimationDelegate:self];

[UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];

• Then you implement the callback

Page 21: iOS Development with Blocks

Replacing Callbacks

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context{

if ([animationID isEqualToString:kIDOne]) {

} else if ([animationID isEqualToString:kIDTwo]) {

}

}

Page 22: iOS Development with Blocks

Replacing Callbacks

• New UIView Animations:

[UIView animateWithDuration:0.3 animations:^{ [myView setAlpha:0.0f]; } completion:^(BOOL finished) { [self doSomething]; }];

Page 23: iOS Development with Blocks

Replacing Callbacks

• New UIView Animations:

[UIView animateWithDuration:0.3 animations:^{ [myView setAlpha:0.0f]; } completion:^(BOOL finished) { [self doSomething]; }];

Page 24: iOS Development with Blocks

Replacing Callbacks

• New UIView Animations:

[UIView animateWithDuration:0.3 animations:^{ [myView setAlpha:0.0f]; } completion:^(BOOL finished) { [self doSomething]; }];

Page 25: iOS Development with Blocks

Replacing Callbacks

• New UIView Animations:

[UIView animateWithDuration:0.3 animations:^{ [myView setAlpha:0.0f]; } completion:^(BOOL finished) { [self doSomething]; }];

Page 26: iOS Development with Blocks

What Are Blocks Good For?

• Replacing Callbacks

• Notification Handlers

• Enumeration

Page 27: iOS Development with Blocks

Notification Handlers

• Old Notifications:

[notificationCenter addObserver:self selector:@selector(foo:) name:kMyNotification object:myObject];

Page 28: iOS Development with Blocks

Notification Handlers

• Old Notifications: Userinfo Dictionaries

- (void)foo:(NSNotification *)aNotification{ NSDictionary *userInfo = [aNotification userInfo]; NSString *UID = [userInfo objectForKey:kIDKey]; NSNumber *value = [userInfo objectForKey:kValueKey];}

Page 29: iOS Development with Blocks

Notification Handlers

• New Notification Handlers:

[notificationCenter addObserverForName:kName object:myObject queue:nil usingBlock:^(NSNotification *aNotification) { [myObject doSomething];}];

[myObject startLongTask];

Page 30: iOS Development with Blocks

What Are Blocks Good For?

• Replacing Callbacks

• Notification Handlers

• Enumeration

Page 31: iOS Development with Blocks

Enumeration

• Basic Enumeration

for (int i = 0; i < [myArray count]; i++) {

id obj = [myArray objectAtIndex:i];

[obj doSomething];

}

Page 32: iOS Development with Blocks

Enumeration

• But…

for (int i = 0; i < [myArray count]; i++) { id obj = [myArray objectAtIndex:i]; [obj doSomething];

for (int j = 0; j < [obj count]; j++) { // Very interesting code here. }}

Page 33: iOS Development with Blocks

Enumeration

• NSEnumerator

NSArray *anArray = // ... ;NSEnumerator *enumerator = [anArray objectEnumerator];

id object;

while ((object = [enumerator nextObject])) {

// do something with object...

}

Page 34: iOS Development with Blocks

Enumeration

• Fast Enumeration (10.5+)

for (id obj in myArray) {

[obj doSomething];

}

Page 35: iOS Development with Blocks

Enumeration

• Block-based enumeration

[myArray enumerateObjectsUsingBlock:

^(id obj, NSUInteger idx, BOOL *stop) {

[obj doSomething];

}];

Page 36: iOS Development with Blocks

Enumeration

• So why use block-based enumeration?

• -enumerateObjectsWithOptions:usingBlock:

• NSEnumerationReverse

• NSEnumerationConcurrent

• Concurrent processing! And for free!

Page 37: iOS Development with Blocks

What Are Blocks Good For?

• Replacing Callbacks

• Notification Handlers

• Enumeration

Page 38: iOS Development with Blocks

What Are Blocks Good For?

• Replacing Callbacks

• Notification Handlers

• Enumeration

• Sorting

Page 39: iOS Development with Blocks

What Are Blocks Good For?

• Replacing Callbacks

• Notification Handlers

• Enumeration

• Sorting

Page 40: iOS Development with Blocks

Sorting

• NSArray

• -sortedArrayWithOptions:usingComparator:

• Concurrent sorting for free!

Page 41: iOS Development with Blocks

Blocks Wrap-Up

^Carat Syntax

^Block Memory Management

^Using Blocks as Arguments

^Replacing Callbacks, Notification Handlers, Enumeration, and Sorting

Page 42: iOS Development with Blocks

Intro to Grand Central Dispatch

Page 43: iOS Development with Blocks

Moore’s Law

• The quantity oftransistors that can be placed inexpensively on an integrated circuit has doubled approximately every two years. The trend has continued for more than half a century and is not expected to stop until 2015 or later.

Wikipedia

Page 44: iOS Development with Blocks

Grand Central Dispatch (GCD)

• Open-source threading library (libdispatch)

• Apache license

• Automatically optimizes threading

• Provides queues, timers, event handlers, etc.

Page 45: iOS Development with Blocks

Simple GCD

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);

dispatch_async(queue, ^{

[self performLongTask];

}

Page 46: iOS Development with Blocks

Basic Dispatch Functions

• dispatch_async(queue, block);dispatch_async_f(queue, context, func);

• Schedules block or function on queue, returns immediately

• dispatch_sync(queue, block);dispatch_sync_f(queue, context, func);

• Schedules block or function on queue, blocks until completion

Page 47: iOS Development with Blocks

Dispatch Queues

• dispatch_queue_t

• Main Queue

• Analogous to main thread (Do your UI operations here)

• dispatch_get_main_queue()

Page 48: iOS Development with Blocks

Global Queues

• dispatch_get_global_queue(priority, flags);

• priority is one of three constants:

• DISPATCH_QUEUE_PRIORITY_LOW

• DISPATCH_QUEUE_PRIORITY_NORMAL

• DISPATCH_QUEUE_PRIORITY_HIGH

• secong arg should always be 0ul (for now)

Page 49: iOS Development with Blocks

Making Queues

• dispatch_queue_create(label, attr)

• Use reverse DNS for label

• com.example.myQueue

• pass NULL for attr

• Be sure to use dispatch_release()

Page 50: iOS Development with Blocks

Using Queues

• Custom queues are serial

• First-in, first-out, one at a time

• Global queues are concurrent

• GCD automatically chooses how many (usually # of CPU cores)