暂时没看却需要看的值得学习iOS博客

GCD

2017-09-25  本文已影响110人  醉看红尘这场梦
3424642-0bba44d41936217e.png

GCD

场景

我们要在iPhone上做一个下载网页的功能,该功能非常简单,就是在iPhone上放置一个按钮,单击按钮的时候,显示一个转动的圆圈,表示正在进行下载,下载完成之后,将内容加载到界面上的一个文本控件中

使用GCD前
#import "ViewController.h"

@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIActivityIndicatorView *indicator;
@property (strong, nonatomic) IBOutlet UILabel *context;

@end

@implementation ViewController

static NSOperationQueue *queue;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)someClick:(id)sender {
    self.indicator.hidden = NO;
    [self.indicator startAnimating];
    queue = [[NSOperationQueue alloc]init];
    NSInvocationOperation *op = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil] autorelease];
    [queue addOperation:op];
}


-(void)download{
    NSURL *url = [NSURL URLWithString:@"http://www.youdao.com"];
    NSError *error;
    NSString *data = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
    
    if(data != nil){
        [self performSelectorOnMainThread:@selector(download_completed:) withObject:data waitUntilDone:NO];
    }else{
        NSLog(@"error when download:%@",error);
        [queue release];
    }
}
-(void)download_completed:(NSString *)data{
    NSLog(@"call back");
    [self.indicator stopAnimating];
    self.indicator.hidden = YES;
    self.context.text = data;
    [queue release];
}
使用GCD后
#import "ViewController.h"

@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIActivityIndicatorView *indicator;
@property (strong, nonatomic) IBOutlet UILabel *context;

@end

@implementation ViewController

static NSOperationQueue *queue;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)someClick:(id)sender {
    self.indicator.hidden = NO;
    [self.indicator startAnimating];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSURL *url = [NSURL URLWithString:@"http://www.youdao.com"];
            NSError *error;
            NSString *data = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
        
            if(data != nil){
                [self performSelectorOnMainThread:@selector(download_completed:) withObject:data waitUntilDone:NO];
            }else{
                NSLog(@"error when download:%@",error);
                [queue release];
            }
    });
}

-(void)download_completed:(NSString *)data{
    NSLog(@"call back");
    [self.indicator stopAnimating];
    self.indicator.hidden = YES;
    self.context.text = data;
    [queue release];
}
blcok的定义
    //声明变量
    (void)(^loggerBlock)(void);
    //定义
    loggerBlock = ^{
        NSLog(@"Hello workd");
    };
    //调用
    loggerBlcok();
    //列如这样
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
       //something
    });
系统提供的dispatch方法
    //后台执行
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
      
    });
    //主线程执行
    dispatch_async(dispatch_get_main_queue(), ^{
        
    });
    //一次性执行
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
    });
    //延迟2秒执行
    double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^{
        
    });
    dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);
    dispatch_async(urls_queue, ^{
        
    });
    dispatch_release(urls_queue);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        //并执行的线程一
    });
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        //并执行的线程二
    });
    dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
        //汇总结果
    });
修改block之外的变量
    __block int a = 0;
    void (^foo)(void) = ^{
        a = 1;
    };
    foo();
    //这里,a的值被修改为1
后台运行
<!--AppDelegate.h-->
@property(assign,nonatomic) UIBackgroundTaskIdentifier backgroundUpdateTask;
<!--AppDelegate.m-->
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}



- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    [self beingBakcgroundUpdateTase];
    [self endBackgounrdUpdateTask];
    
}

-(void)beingBakcgroundUpdateTase{
    self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [self endBackgounrdUpdateTask];
    }];
}

-(void)endBackgounrdUpdateTask{
    [[UIApplication sharedApplication] endBackgroundTask:self.backgroundUpdateTask];
    self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}
总结
总体来说,GCD能够极大地方方便开发者进行多线程编程,大家应该尽量使用GCD来处理后台线程和UI线程的交互
上一篇 下一篇

猜你喜欢

热点阅读