当前位置: 首页 > news >正文

网站备案需要钱吗建筑设计师用什么软件

网站备案需要钱吗,建筑设计师用什么软件,5000以上扣税标准表,微网站在线制作前言#xff1a; 最近在写需求的时候用到了DispatchGroup#xff0c;一直没有深入去学习#xff0c;既然遇到了那么就总结下吧。。。。 基本介绍#xff1a; 任务组#xff08;DispatchGroup#xff09; DispatchGroup 可以将多个任务组合在一起并且监听它们的完成状态。…前言 最近在写需求的时候用到了DispatchGroup一直没有深入去学习既然遇到了那么就总结下吧。。。。 基本介绍 任务组DispatchGroup DispatchGroup 可以将多个任务组合在一起并且监听它们的完成状态。当所有任务都完成时可以通过通知回调或等待的方式知道它们的执行结果。 let group DispatchGroup() let queue DispatchQueue(label: .com1,attributes: .concurrent)queue.async(group: group) {print(任务1完成) }queue.async(group: group) {print(任务2完成) }// 当所有任务完成时通知 group.notify(queue: DispatchQueue.main) {print(所有任务完成) }// 或者阻塞等待所有任务完成 group.wait() print(所有任务完成等待方式) 输出 任务2完成 任务1完成 所有任务完成等待方式 所有任务完成 正文 Swift使用的GCD是桥接OC的源码。所以底层还是libdispatch。 可以去github上Apple官方仓库去下载GitHub - swiftlang/swift-corelibs-libdispatch: The libdispatch Project, (a.k.a. Grand Central Dispatch), for concurrency on multicore hardware 下载源码后可以在semaphore.c中找到DispatchGroup的实现。 create 先来看看dispatch_group_create的实现 dispatch_group_create(void) {return _dispatch_group_create_with_count(0); } 可以看到创建dispatch_group涉及到_dispatch_group_create_with_count(long count) 那我们看下_dispatch_group_create_with_count()的源码 DISPATCH_ALWAYS_INLINE static inline dispatch_group_t _dispatch_group_create_with_count(long count) {//dispatch_group_t就是dispatchGroup//dispatch_group_t本质上就是dispatch_group_s 详见下方dispatch_group_t dg (dispatch_group_t)_dispatch_object_alloc(DISPATCH_VTABLE(group), sizeof(struct dispatch_group_s));//把count的值存进去结构体_dispatch_semaphore_class_init(count, dg);//如果有值 就执行os_atomic_store2oif (count) {os_atomic_store2o(dg, do_ref_cnt, 1, relaxed); // rdar://problem/22318411}return dg; } 我们一个一个来分析 通过搜索发现dispatch_group_t本质上就是dispatch_group_s dispatch_group_s其实是一个结构体其代码如下 struct dispatch_group_s {DISPATCH_SEMAPHORE_HEADER(group, dg);//看名字知道和wait方法有关int volatile dg_waiters;//dispatch_continuation_s可以自行搜索 最后是个dispatch_object_s//这里可以理解为存储一个链表的 链表头和尾。看参数名知道和notify有关struct dispatch_continuation_s *volatile dg_notify_head;struct dispatch_continuation_s *volatile dg_notify_tail; }; creat创建了一个dispatch_group_t也是dispatch_group_s出来默认传进来的count是0并且把count通过dispatch_semaphore_class_init(count, dg)存了起来。 我们再来看看dispatch_semaphore_class_init(count, dg)的代码 //_dispatch_semaphore_class_init(count, dg); static void _dispatch_semaphore_class_init(long value, dispatch_semaphore_class_t dsemau) { //dsemau就是dg 本质就是把传递进来的count存起来struct dispatch_semaphore_header_s *dsema dsemau._dsema_hdr;dsema-do_next DISPATCH_OBJECT_LISTLESS;dsema-do_targetq _dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, false);//value就是传进来的countdsema-dsema_value value;_dispatch_sema4_init(dsema-dsema_sema, _DSEMA4_POLICY_FIFO); } 通过creat方法我们知道我们创建了一个dispatch_group_s出来并且把0存了起来。知道dispatch_group_s中有一个类似链表的头和尾看参数名知道和notify有关。 enter enter() 本质上调用dispatch_group_enter() 其代码如下 void dispatch_group_enter(dispatch_group_t dg) {//os_atomic_inc_orig2o是宏定义可以一直点进去看。本质上就是把dg的dg_value做1操作。long value os_atomic_inc_orig2o(dg, dg_value, acquire);if (slowpath((unsigned long)value (unsigned long)LONG_MAX)) {DISPATCH_CLIENT_CRASH(value,Too many nested calls to dispatch_group_enter());}if (value 0) {_dispatch_retain(dg); // rdar://problem/22318411} } 其实dispatch_group_enter只是把dg的dg_value做一个1的操作。如果dg_value值过大就会crash。如果dg_value为0就会释放 leave() void dispatch_group_leave(dispatch_group_t dg) {//dg_value -1long value os_atomic_dec2o(dg, dg_value, release);if (slowpath(value 0)) {//当value0 执行_dispatch_group_wakereturn (void)_dispatch_group_wake(dg, true);}//不成对出现 crashif (slowpath(value 0)) {DISPATCH_CLIENT_CRASH(value,Unbalanced call to dispatch_group_leave());} } 与enter相反做减1操作。 从源码得知leave的核心逻辑是判断value0时候执行_dispatch_group_wake。同时当levae次数比enter多时候value0会crash 可以说DispatchGroup的核心逻辑就在_dispatch_group_wake方法中 _dispatch_group_wake 代码如下 DISPATCH_NOINLINE static long _dispatch_group_wake(dispatch_group_t dg, bool needs_release) {dispatch_continuation_t next, head, tail NULL;long rval;// cannot use os_mpsc_capture_snapshot() because we can have concurrent// _dispatch_group_wake() calls//dispatch_group_s 中dg_notify_headhead os_atomic_xchg2o(dg, dg_notify_head, NULL, relaxed);if (head) {// snapshot before anything is notified/woken rdar://problem/8554546tail os_atomic_xchg2o(dg, dg_notify_tail, NULL, release);}rval (long)os_atomic_xchg2o(dg, dg_waiters, 0, relaxed);if (rval) {// wake group waiters_dispatch_sema4_create(dg-dg_sema, _DSEMA4_POLICY_FIFO);_dispatch_sema4_signal(dg-dg_sema, rval);}uint16_t refs needs_release ? 1 : 0; // rdar://problem/22318411if (head) {// async group notify blocksdo {next os_mpsc_pop_snapshot_head(head, tail, do_next);dispatch_queue_t dsn_queue (dispatch_queue_t)head-dc_data;//head就是notify的block 在目标队列dsn_queue上运行_dispatch_continuation_async(dsn_queue, head);_dispatch_release(dsn_queue);} while ((head next));refs;}if (refs) _dispatch_release_n(dg, refs);return 0; } 是否还记得前面提到的dispatch_group_s中的链表头和尾 head os_atomic_xchg2o(dg, dg_notify_head, NULL, relaxed); _dispatch_group_wake的代码前半部分其实是这里取出dispatch_group_s中的链表头如果有链表头再取出链表尾。执行的真正逻辑在do_while中我们截出来研究 if (head) {// async group notify blocksdo {next os_mpsc_pop_snapshot_head(head, tail, do_next);dispatch_queue_t dsn_queue (dispatch_queue_t)head-dc_data;//head就是notify的block 在目标队列dsn_queue上运行_dispatch_continuation_async(dsn_queue, head);_dispatch_release(dsn_queue);} while ((head next));refs;}通过head-dc_data拿到目标队列然后通过_dispatch_continuation_async(dsn_queue, head)将head运行在目标队列上。 那么head其实就是任务队列这个队列中存储的是notify回调的block 这时候我们回头看dispatch_group_s的定义 struct dispatch_group_s {DISPATCH_SEMAPHORE_HEADER(group, dg);//看名字知道和wait方法有关int volatile dg_waiters;//这里就是把所有notify的回调block存进链表里然后拿到头结点和尾结点。struct dispatch_continuation_s *volatile dg_notify_head;struct dispatch_continuation_s *volatile dg_notify_tail; }; 总结 DispatchGroup 在创建时候会建立一个链表来存储notify的block回调。判断notify执行的依据就是dg_value是否为0当不调用enter和leave时候dg_value0notify的回调会立即执行并且有多个notify会按照顺序依次调用。当有enter时候dg_value1。leave时候-1。当最后一个leave执行后dg_value0。去循环链表执行notify的回调根据源码也得知enter和leave必须成对出现 当enter多的时候dg_value永远大于0notify不会被执行。 当leave多的时候dg_value小于0造成Crash 参考 从源码分析Swift多线程—DispatchGroup | licc 一文看懂iOS多线程并发(NSThread、GCD、NSOperationNSOperationQueue)_ios nsstread nsoperation gcd-CSDN博客 GitHub - swiftlang/swift-corelibs-libdispatch: The libdispatch Project, (a.k.a. Grand Central Dispatch), for concurrency on multicore hardware
http://www.sczhlp.com/news/256175/

相关文章:

  • 义乌网站建设制作商温州高端网站建设
  • 2025年耐用的冲压机械手厂家推荐及采购参考
  • Fiddler更换图片
  • Vue3技术实践总结与未来展望
  • 2025年11月自动挡重卡选哪家:正规厂家实力排名前十对比
  • 2025年靠谱的全自动高压隔膜压滤机厂家最新用户好评榜
  • 网站联系我们 怎么做地图山东网优
  • 北京手机网站建设外包网站如何设置长尾词
  • 有口碑的大良网站建设建设集团招工信息网站
  • 原材料价格查询网站大兴专注高端网站建设
  • 专做特卖的网站建设工程合同补充协议范本
  • 网站建设签约360海南地方网站
  • 写作网站哪个能得稿费网站dw建设
  • 创新的成都 网站建设如何提高wordpress后台的访问速度
  • 济南做网站哪家好怎么选现在网络推广有哪些平台
  • 网站服务器租用和托管门户网站 源码
  • 500做网站网站建设用源码
  • 网站建设中的财务预算WordPress 分类目录 加斜杠
  • 电子商务网站的建设方法望野翻译
  • 重庆门户网站华龙网麦当劳订餐网站 是谁做的
  • 最好的产品网站建设做视频网站被判刑
  • 在线网站建设哪个正规荥阳seo
  • 点击一个网站跳转到图片怎么做精准客户电话号码资源
  • 建筑规范网站自己做的网页怎么上传网站吗
  • 企业门户网站静态模板nginx 反向代理 wordpress
  • 开发网站做什么wordpress 5.1不提示自动更新
  • 公司网站建设报告极简简历官网
  • 江苏住房城乡建设部网站wordpress 字符截取
  • 2025年知名的冷却塔清淤机器人厂家最新推荐排行榜
  • 2025年11月自动挡重卡生产厂家热门排行:诚信耐用车型权威评价榜