GCD执行UI相关的任务
UI相关的任务只能在主线程中执行,所以用GCD编程,你只能把UI相关任务分配给主队列来执行。利用dispatch_get_main_queue可以获得主队列的句柄。
有两种方式可以把任务分配给主队列。他们都是异步的:
dispatch_async 执行block对象
dispatch_async_f 执行c函数
dispatch_sync不应该在主队列中被调用,因为这将造成死锁。所以所有通过GCD提交给主队列的任务都必须是异步的。
dispatch_async函数接收两个参数:
Dispatch queue handle 将执行此任务的队列
Block object 发送给队列异步执行的block对象
来看个例子,这段代码将会在屏幕上显示一个提示框:
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^(void) {
[[[UIAlertView alloc] initWithTitle:@"GCD"
message:@"GCD is amazing!"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil, nil] show];
});
当然了这没什么好神奇的,子线程主要是用来干体力活的。
还是当然了,这个功能可以用dispatch_async_f来实现的。代码呢,自己想吧。
1,首先创建结构体
typedef struct{
char *title;
char *message;
char *cancelButtonTitle;
} AlertViewData;
2,接收此结构体指针的c函数
void displayAlertView(void *paramContext){
AlertViewData *alertData = (AlertViewData *)paramContext;
NSString *title =
[NSString stringWithUTF8String:alertData->title];
NSString *message =
[NSString stringWithUTF8String:alertData->message];
NSString *cancelButtonTitle =
[NSString stringWithUTF8String:alertData->cancelButtonTitle];
[[[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:cancelButtonTitle
otherButtonTitles:nil, nil] show];
free(alertData);
}
为什么在此函数内释放结构体控件呢?因为异步,调用者创建空间后,
根本不知道什么时候执行完该函数,所以这份工作就留给这个函数做咯。
3,好吧,看下人家怎么用吧
- (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
dispatch_queue_t mainQueue = dispatch_get_main_queue();
AlertViewData *context = (AlertViewData *)malloc(sizeof(AlertViewData));
if (context != NULL){
context->title = "GCD";
context->message = "GCD is amazing.";
context->cancelButtonTitle = "OK";
dispatch_async_f(mainQueue,(void *)context,displayAlertView);
}
self.window = [[UIWindow alloc] initWithFrame:
[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
话说这个block对象真的是在主线程中运行的吗?做下试验
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^(void) {
NSLog(@"Current thread = %@", [NSThread currentThread]);
NSLog(@"Main thread = %@", [NSThread mainThread]);
});
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
输出结果是:
Current thread = <NSThread: 0x4b0e4e0>{name = (null), num = 1}
Main thread = <NSThread: 0x4b0e4e0>{name = (null), num = 1}
我也没试,既然都这样了,那就信了吧