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

iOS Development with Blocks

Jun 22, 2015

Download

Technology

Jeff Kelley

Slides from Jeff Kelley’s MobiDevDay presentation on blocks and iOS.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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)