LazyDispatch 0.0.1

LazyDispatch 0.0.1

测试已测试
Lang语言 Obj-CObjective C
许可 MIT
Released最后发布2014年12月

未注册 维护。



  • 作者
  • Rasmus Andersson

懒调度

在 libdispatch (也称为 Grand Central Dispatch) 之上实现的一个非常薄的 API 和概念,用于 Cocoa Objective-C 代码。

我是个懒人,所以当我不得不写很多的代码来做这样一些众所周知的事情,比如在不同的调度队列中安排各种代码块的时候,就会感到痛苦。这个小工具让我用更少的代码完成工作,并且结果也更容易阅读。

示例

首先,使用纯 libdispatch

dispatch_queue_t parentQueue = dispatch_get_current_queue();
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  NSLog(@"Block #1 on queue '%s' (parentQueue: '%s')",
        dispatch_queue_get_label(dispatch_get_current_queue()),
        dispatch_queue_get_label(parentQueue));

  dispatch_queue_t parentQueue2 = dispatch_get_current_queue();
  dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"Block #2 on queue '%s'",
          dispatch_queue_get_label(dispatch_get_current_queue()));

    dispatch_async(parentQueue2, ^{
      NSLog(@"Block #3 on queue '%s'",
            dispatch_queue_get_label(dispatch_get_current_queue()));
      exit(0);
    });
  });
});

现在,使用 LazyDispatch

sched_background ^(DQueue parentQueue){
  NSLog(@"Block #1 on queue '%s' (parentQueue: '%s')",
        DQueueID(__queue), DQueueID(parentQueue));

  sched_main ^(DQueue parentQueue){
    NSLog(@"Block #2 on queue '%s'", DQueueID(__queue));

    sched(parentQueue) ^{
      NSLog(@"Block #3 on queue '%s'", DQueueID(__queue));
    };
  };
};
Block #1 on queue 'com.apple.root.default-priority' (parentQueue: 'com.apple.main-thread')
Block #2 on queue 'com.apple.main-thread'
Block #3 on queue 'com.apple.root.default-priority'

看吧。简单多了,性能相同,因为没有增加任何实际的开销。我们只是把东西重新表述了一下,使其更易于阅读。

哇!我现在可以玩得更开心了!

还有定时器。我们都很爱它们,不是吗?

sched_delay(1, ^{
  NSLog(@"Delayed block executed after one second");
});

就像 JavaScript 一样,定时器可以被取消

DTimer timer = sched_interval(13.37, ^{
  NSLog(@"Delayed block sez hi");
});
//...
DTimerStop(timer);

API

类型

  • DQueue — 一个调度队列(dispatch_queue_t 的别名)
  • DBlock — 一个块(dispatch_block_t 的别名)
  • DTimer — 一个定时器(dispatch_source_t 的别名)

特殊变量

  • __queueDQueue — 当前队列
  • __main_queueDQueue — 主队列

关键字表达式

sched_background ^([DQueue parentQueue]) → block

在后台队列中安排一个块。块可以接受一个可选参数,这将是从 sched_background 调用的队列。表达式的结果是块本身。

这对于调用回调并将控制权返回到同一队列非常有用,例如

- (void)doSomethingFunkyWithCallback:(DBlock)callback {
  sched_background ^(DQueue parentQueue){
    // work work work ...
    sched(parentQueue) callback;
  };
}

sched_main ^([DQueue parentQueue]) → block

在主队列中安排一个块。块可以接受一个可选参数,这将是从 sched_main 调用的队列。表达式的结果是块本身。

sched(DQueue queue) ^([DQueue parentQueue]) → block

在队列中安排一个块。该块可以选择接受一个参数,该参数将是调用 sched 后的队列。表达式的结果是该块本身。

函数

const char* DQueueID(DQueue queue)

访问 queue(其“标签”)的易读标识符

DTimer sched_delay(NSTimeInterval delay, ^([DTimer[, DQueue]]))

在当前队列中安排一个块,该块将在 delay 秒后执行。您可以通过调用(从该函数返回的)DTimer 对象上的 DTimerStop 来在计时器触发前取消计时光标。

示例

// Schedule a block to be run after a delay of one second
sched_delay(1, ^{
  NSLog(@"Delayed block triggered");
});

DTimer sched_interval(NSTimeInterval interval, ^([DTimer[, DQueue]]))

在当前队列中安排一个块,每隔 interval 秒执行一次。您需要在不再需要计时器时调用 DTimerStop(timer)

示例

// Schedule a block to be run every 1.1 seconds
sched_interval(1.1, ^{
  NSLog(@"Perpetual block triggered");
});

DTimer sched_timer(DQueue queue, NSTimeInterval delay, NSTimeInterval interval, ^([DTimer[, DQueue]]))

queue 上安排一个计时器,在 delay 秒后开始运行,并每隔 interval 重复。

如果 interval 具有正值,计时器将每 interval 秒重复一次。在这种情况下,您负责通过调用 DTimerStop(timer) 停止计时光标。如果 interval 为零或负数,计时器只触发一次,然后自动停止。

示例

// Start a timer on `fooQueue` after 1.5 seconds, triggering in 3.5 second intervals
sched_timer(fooQueue, 1.5, 3.5, ^(DTimer timer){
  NSLog(@"Timer %@ triggered on foo queue", timer);
});

DTimer DTimerCreate(DQueue queue, NSTimeInterval delay, NSTimeInterval interval, ^([DTimer[, DQueue]]))

sched_timer 相似,但仅创建计时器(不会对其进行安排)。您需要调用 DTimerResume 以安排计时器。

示例

DTimer timer = DTimerCreate(fooQueue, 1.5, 3.5, ^(DTimer timer){
  NSLog(@"Timer %@ triggered on foo queue", timer);
});
// ...
DTimerResume(timer);

DTimer DTimerResume(DTimer timer)

安排尚未安排的计时器(由 DTimerPause 暂停或由 DTimerCreate 刚创建。)

每次调用 DTimerResume 都必须平衡一个调用到 DTimerPause,否则将出现内存违规,可能导致所有东西崩溃。这是 libdispatch 的特性,以使用容错和效率进行交换。请注意,从 sched_delaysched_intervalsched_timer 返回的计时器已经恢复了。

DTimer DTimerPause(DTimer timer)

取消已安排的计时器。在暂停计时器并在稍后恢复它时,触发时间不会根据计时器暂停期间的时间进行调整。

DTimer DTimerSetInterval(DTimer timer, NSTimeInterval interval)

修改和重置计时器的间隔。

如果计时器源已被取消,调用此函数不会产生影响。

示例

// Execute a block five times with 1 second interval, then change the interval to
// execute the block with 2 seconds interval.
__block int triggerCount = 0;
sched_interval(1.0, ^(DTimer timer){
  NSLog(@"Perpetual block triggered");
  if (++triggerCount == 5) {
    DTimerSetInterval(timer, 2.0);
  }
});

void DTimerStop(DTimer timer)

取消操作将防止进一步调用指定定时器的处理程序块,但不会中断正在执行的处理程序块。

MIT许可证

版权所有(c)2012 拉斯穆斯· andersson http://rsms.me/

在此特此准许任何人免费获取此软件及其相关文档(以下简称“软件”)副本,无论出于任何目的使用、复制、修改、合并、发布、分发、再许可或出售软件副本,并允许向软件提供副本的个人执行上述行为,前提是遵守以下条件

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

软件按“原样”提供,不提供任何形式的担保,包括但不限于适销性、针对特定目的的适用性和非侵权性担保。在任何情况下,作者或版权所有者对任何索赔、损害或其他责任,无论源于合同、侵权或其他,因软件或其使用或其他方式产生或与之相关均不承担任何责任。