iOS Development with Blocks
-
Upload
jeff-kelley -
Category
Technology
-
view
5.875 -
download
0
description
Transcript of iOS Development with Blocks
![Page 1: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/1.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/2.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/3.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/4.jpg)
Your First Block
void (^helloWorldBlock)(void) = ^ {
printf ("Hello, World!\n");
};
![Page 5: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/5.jpg)
Calling Your First Block
void (^helloWorldBlock)(void) = ^ {
printf ("Hello, World!\n");
};
helloWorldBlock();
![Page 6: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/6.jpg)
Blocks That Return
• Blocks return just like functions.
int (^fortyTwo)(void) = ^{
return 42;
}
int a = fortyTwo();
![Page 7: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/7.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/8.jpg)
Blocks Capture Scope
int a = 42;
void (^myBlock)(void) = ^{
printf("a = %d\n", a);
};
myBlock();
![Page 9: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/9.jpg)
int a = 42;
void (^myBlock)(void) = ^{
a++;
printf("a = %d\n", a);
};
myBlock();
![Page 10: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/10.jpg)
__block int a = 42;
void (^myBlock)(void) = ^{
a++;
printf("a = %d\n", a);
};
myBlock();
![Page 11: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/11.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/12.jpg)
Using Blocks as Arguments
• Method Signature:
• - (void)doThisBlock:(void (^)(id obj))block
• returns void, takes id argument
![Page 13: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/13.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/14.jpg)
Block Scope
void (^myBlock)(void);
if (someValue == YES) {
myBlock = ^{ printf("YES!\n") };
} else {
myBlock = ^ { printf("NO!\n") };
}
![Page 15: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/15.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/16.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/17.jpg)
NSString *helloWorld = [[NSString alloc] initWithString:@"Hello, World!"];
void (^helloBlock)(void) = ^{
NSLog(@"%@", helloWorld);
};
[helloWorld release];
helloBlock();
Blocks Retain Objects
![Page 18: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/18.jpg)
What Are Blocks Good For?
• Replacing Callbacks
• Notification Handlers
• Enumeration
![Page 19: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/19.jpg)
What Are Blocks Good For?
• Replacing Callbacks
• Notification Handlers
• Enumeration
![Page 20: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/20.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/21.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/22.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/23.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/24.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/25.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/26.jpg)
What Are Blocks Good For?
• Replacing Callbacks
• Notification Handlers
• Enumeration
![Page 27: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/27.jpg)
Notification Handlers
• Old Notifications:
[notificationCenter addObserver:self selector:@selector(foo:) name:kMyNotification object:myObject];
![Page 28: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/28.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/29.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/30.jpg)
What Are Blocks Good For?
• Replacing Callbacks
• Notification Handlers
• Enumeration
![Page 31: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/31.jpg)
Enumeration
• Basic Enumeration
for (int i = 0; i < [myArray count]; i++) {
id obj = [myArray objectAtIndex:i];
[obj doSomething];
}
![Page 32: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/32.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/33.jpg)
Enumeration
• NSEnumerator
NSArray *anArray = // ... ;NSEnumerator *enumerator = [anArray objectEnumerator];
id object;
while ((object = [enumerator nextObject])) {
// do something with object...
}
![Page 34: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/34.jpg)
Enumeration
• Fast Enumeration (10.5+)
for (id obj in myArray) {
[obj doSomething];
}
![Page 35: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/35.jpg)
Enumeration
• Block-based enumeration
[myArray enumerateObjectsUsingBlock:
^(id obj, NSUInteger idx, BOOL *stop) {
[obj doSomething];
}];
![Page 36: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/36.jpg)
Enumeration
• So why use block-based enumeration?
• -enumerateObjectsWithOptions:usingBlock:
• NSEnumerationReverse
• NSEnumerationConcurrent
• Concurrent processing! And for free!
![Page 37: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/37.jpg)
What Are Blocks Good For?
• Replacing Callbacks
• Notification Handlers
• Enumeration
![Page 38: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/38.jpg)
What Are Blocks Good For?
• Replacing Callbacks
• Notification Handlers
• Enumeration
• Sorting
![Page 39: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/39.jpg)
What Are Blocks Good For?
• Replacing Callbacks
• Notification Handlers
• Enumeration
• Sorting
![Page 40: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/40.jpg)
Sorting
• NSArray
• -sortedArrayWithOptions:usingComparator:
• Concurrent sorting for free!
![Page 41: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/41.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/42.jpg)
Intro to Grand Central Dispatch
![Page 43: iOS Development with Blocks](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/43.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/44.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/45.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/46.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/47.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/48.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/49.jpg)
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](https://reader033.fdocuments.us/reader033/viewer/2022052905/55871190d8b42a8a3f8b466d/html5/thumbnails/50.jpg)
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)