十五章--GCD,background

已经快变成了强迫症了,看完了喜欢的东西一定要写出来,否则好像就过段时间就没有了一样。

这一章出现了很多的概念,也是iOS的特色吧,让我回想一下有哪些,哦,大概是以下这些:GCD、多线程、主线程队列获取、Block、Sleep、 UIKit 线程安全、UIActivityIndicatorView控件、实现程序在后台长久运行、NSUserDefault保存用户数据、_cmd使用等。

一、GCD--Grand Central Dispatch(中央任务调度)

      这个是Apple开发的一个多核编程的解决方法。

     让我们看看实例中的使用,最重要的那段:(为了简洁,就不全写了)

dispatch_queue_t queue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{。。。。。。
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
。。。。。。
});
dispatch_group_async(group, queue, ^{
。。。。。。
});
dispatch_group_notify(group, queue, ^{
。。。。。。;
dispatch_async(dispatch_get_main_queue(), ^{
。。。。。。//这里实现UIView的显示,为了UIKit线程安全,只能在主线程中实现
});
。。。。。。
});
});

详细解释一下:

  ^{},这种就是Block的使用,类似C#的Lamda表示方法或是C的函数指针,前面专门写了一章。

dispatch queue分成以下三种:

1)运行在主线程的Main queue,通过dispatch_get_main_queue获取。可以看出,dispatch_get_main_queue也是一种dispatch_queue_t。

2)并行队列global dispatch queue,通过dispatch_get_global_queue获取,由系统创建三个不同优先级的dispatch queue。并行队列的执行顺序与其加入队列的顺序相同。

3)串行队列serial queues一般用于按顺序同步访问,可创建任意数量的串行队列,各个串行队列之间是并发的。

当想要任务按照某一个特定的顺序执行时,串行队列是很有用的。串行队列在同一个时间只执行一个任务。我们可以使用串行队列代替锁去保护共享的数据。和锁不同,一个串行队列可以保证任务在一个可预知的顺序下执行。

serial queues通过dispatch_queue_create创建,可以使用函数dispatch_retain和dispatch_release去增加或者减少引用计数。

解释下上面的结构:

dispatch_async(dispatch_get_global_queue(0,0), ^{} //后台异步执行并行队列

dispatch_group_async(group,queue, ^{} //并行执行的线程一

dispatch_group_async(group,queue, ^{} //并行执行的线程二

dispatch_group_notify(group, queue, ^{} //并行执行完后的汇总

dispatch_async(dispatch_get_main_queue(), ^{} //异步执行获取主线程队列

二、几种状态

委派方法通知名称

application:didFinishLaunchingWithOptions: UIApplicationDidFinishLaunchingNotification
applicationWillResignActive: UIApplicationWillResignActiveNotification
applicationDidBecomeActive: UIApplicationDidBecomeActiveNotification
applicationDidEnterBackground: UIApplicationDidEnterBackgroundNotification
applicationWillEnterForeground: UIApplicationWillEnterForegroundNotification
applicationWillTerminate: UIApplicationWillTerminateNotification

状态的概念是最好理解的,几种:启动、撤销活动、进入后台、进入前台、终端程序

三、让程序在后台较长久的运行

    GCD的另一个用处是可以让程序在后台较长久的运行。在没有使用GCD时,当app被

按home键退出后,app仅有最多5秒钟的时候做一些保存或清理资源的工作。但是在使

用GCD后,app最多有10分钟的时间在后台长久运行。这个时间可以用来做清理本地缓

存,发送统计数据等工作。利用beginBackgroundTaskWithExpirationHandler:^{}

   实例中的使用方法:

   UIApplication *app = [UIApplication sharedApplication];
    __block UIBackgroundTaskIdentifier taskId;
    taskId = [app beginBackgroundTaskWithExpirationHandler:^{
     NSLog(@"Background task ran out of time and was terminated.");
     [app endBackgroundTask:taskId];}];
     if (taskId == UIBackgroundTaskInvalid) {
     NSLog(@"Failed to start background task!");
     return;}
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
     NSLog(@"Starting background task with %f seconds remaining",
     app.backgroundTimeRemaining);

     [NSThread sleepForTimeInterval:25];
     NSLog(@"Finishing background task with %f seconds remaining",
     app.backgroundTimeRemaining);
     [app endBackgroundTask:taskId];
     });

     标准的使用方法:

     

// AppDelegate.h文件
@property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundUpdateTask;

// AppDelegate.m文件
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [self beingBackgroundUpdateTask];
    // 在这里加上你需要长久运行的代码
    [self endBackgroundUpdateTask];
}

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

- (void)endBackgroundUpdateTask
{
    [[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
    self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}

四、几种小的概念和方法

    1、sleep

    [NSThread sleepForTimeInterval:4];

     2、活动指示器控件

    UIActivityIndicatorView

     3、 _cmd的使用

     _cmd是iOS内置变量,始终指向当前方法的selector

    4、状态加入事件通知中心

     [center addObserver:self selector:@selector(applicationWillResignActive)
        name:UIApplicationWillResignActiveNotification  object:nil];

    5、用NSUserDefault保存用户数据

          使用方法:  

          保存:

          NSInteger selectedIndex = self.segmentedControl.selectedSegmentIndex;
          [[NSUserDefaults standardUserDefaults] setInteger:selectedIndex
          forKey:@"selectedIndex"];

         取出:

          NSNumber *indexNumber = indexNumber = [[NSUserDefaults standardUserDefaults]
          objectForKey:@"selectedIndex"];
          if (indexNumber) {
           NSInteger selectedIndex = [indexNumber intValue];
           self.segmentedControl.selectedSegmentIndex = selectedIndex;}




你可能感兴趣的:(十五章--GCD,background)