您的位置:首页 > 其它

Grand Central Dispatch

2012-08-01 09:42 169 查看
原文地址:/article/7013755.html

Grand Central Dispatch

使用GCD,可以让你的程序不会失去响应. 多线程不容易使用,用了GCD,会让它变得简单。你无需专门进行线程管理, 很棒!

让你的程序保持响应的原则:

1. 不要柱塞主线程

2. 把工作一到其他线程中做。

3. 做完后更新主线程的UI.

没有GCD的代码:

- (void)addTweetWithMsg:(NSString*)msg url:(NSURL*)url {

// Controller UI callback on main thread

DTweet *tw = [[DTweet alloc] initWithMsg:msg];

[tweets addTweet:tw display:YES];

tw.img = [imageCache getImgFromURL:url];//bottle neck

[tweets updateTweet:tw display:YES];

[tw release];

}

有GCD的代码:

- (void)addTweetWithMsg:(NSString*)msg url:(NSURL*)url {

// Controller UI callback on main thread

DTweet *tw = [[DTweet alloc] initWithMsg:msg];

[tweets addTweet:tw display:YES];

dispatch_async(image_queue, ^{

tw.img = [imageCache getImgFromURL:url];

dispatch_async(main_queue, ^{

[tweets updateTweet:tw display:YES];

});

});

[tw release];

}

GCD Queues

1. Lightweight list of blocks

2. Enqueue/dequeue is FIFO

3. Enqueue with dispatch_async()

4. Dequeue by automatic thread or main thread

Main Queue

1. Executes blocks one at a time on main thread

2. Cooperates with the UIKit main run loop

3. dispatch_get_main_queue()

Creating your own queues

1. Execute blocks one at a time

2. On automatic helper thread

3. “Queue up” background work

dispatch_queue_t queue;

queue = dispatch_queue_create(“com.example.purpose”, NULL);

dispatch_release(queue);

Queues Instead of Locks

1. Enqueuing is thread-safe.

2. Execution is serial

3. Protect access to shared data

4. Queues are lightweight

Managing Queue Lifetime

1. Queues are reference counted. dispatch_retain() / dispatch_release()

2. GCD retains parameters to dispatch API as necessary

3. Ensure correct queue lifetime across asynchronous operations

4. Ensure objects captured by blocks are valid when blocks are executed

5. Objective-c objects are auto-retained/released

6 Other objects must be retained by your code. CFRetain() / CFRelease()

- (void)asyncParseData:(NSData *)date

queue:(dispatch_queue_t)queue

block:(void (^)(id result))block {

dispatch_retain(queue);

dispatch_async(self.parse_queue, ^{

id result = [self parseData:data];

dispatch_async(queue, ^{

block(result);

});

dispatch_release(queue);

});

}

App Design with Queues

Demo app tasks

1. Receive and parse network stream

2. Maintain message history

3. Fetch and cache images

4. Display user interface

Without GCD

NSData *d = [twitterStream receiveData];

DTweet *tw = [[DTweet alloc] initWithData:d];

[[tweets addTweet:tw];

[viewController displayTweet:tw]; });

tw.img = [imageCache getImgFromURL:tw.url];

[viewController updateTweetDisplay:tw];

[tw release];

With GCD

dispatch_async(network_queue, ^{

NSData *d = [twitterStream receiveData];

DTweet *tw = [[DTweet alloc] initWithData:d];

dispatch_async(tweets_queue, ^{

[[tweets addTweet:tw];

dispatch_async(main_queue, ^{

[viewController displayTweet:tw]; });

});

dispatch_async(image_queue, ^{

tw.img = [imageCache getImgFromURL:tw.url];

dispatch_async(main_queue, ^{

[viewController updateTweetDisplay:tw];

});

});

});

[tw release];

});

Pitfalls

1. Avoid blocking per-subsystem queues

2. Be careful when waiting. (deadlock)

3. Blocked worker threads consume resources

Responding to External Events

Dispatch sources

1. Monitor external events

- Files, Network Sockets, Directories, Timers

2. Event handlers can be delivered to any queue

3. Use sources to replace polling or blocking API calls

4. See session 211:

Simplifying iPhone App Development with Grand Central Dispatch

Where do I find GCD?

1. GCD is part of libSystem.dylib

2. #include <dispatch/dispatch.h>

WWDC2010 Session206 Introducing Blocks and Grand Central Dispatch on iPhone

Author: Kevin van Vechten - Manager, Core OS

Block, GrandCentralDispatch, WWDC2010, 学习笔记
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: