objective-c-dispatch_sync与主队列上的dispatch_async

objective-c-dispatch_sync与主队列上的dispatch_async,第1张

概述与我一起,这将要采取一些解释。我有一个看起来像下面的功能。 上下文:“aProject”是名为LPProject的核心数据实体,名为“memberFiles”的数组包含另一个名为LPFile的核心数据实体的实例。每个LPFile表示磁盘上的文件,我们要做的是打开每个文件并解析其文本,查找指向OTHER文件的@import语句。如果我们找到@import语句,我们要定位他们指向的文件,然后通过向表示 与我一起,这将要采取一些解释。我有一个看起来像下面的功能。

上下文:“aProject”是名为LPProject的核心数据实体,名为“memberfiles”的数组包含另一个名为LPfile的核心数据实体的实例。每个LPfile表示磁盘上的文件,我们要做的是打开每个文件并解析其文本,查找指向OTHER文件的@import语句。如果我们找到@import语句,我们要定位他们指向的文件,然后通过向表示第一个文件的核心数据实体添加关系将该文件“链接”到该文件。因为所有这些都需要一些时间在大型文件,我们将使用GCD的主线程。

- (voID) establishimportlinksForfilesInProject:(LPProject *)aProject {    dispatch_queue_t taskQ = dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAulT,0);     for (LPfile *filetocheck in aProject.memberfiles) {         if (//Some condition is met) {            dispatch_async(taskQ,^{                // Here,we do the scanning for @import statements.                 // When we find a valID one,we put the whole path to the imported file into an array called 'verifIEdimports'.                 // go back to the main thread and update the model (Core Data is not thread-safe.)                dispatch_sync(dispatch_get_main_queue(),^{                    NSLog(@"Got to main thread.");                    for (Nsstring *import in verifIEdimports) {                              // Add the relationship to Core Data LPfile entity.                    }                });//end block            });//end block        }    }}

现在,这里的东西变得奇怪:

这段代码工作,但我看到一个奇怪的问题。如果我在一个有几个文件(约20)的LPProject上运行它,它运行完美。但是,如果我在有更多文件(例如,60-70)的LPProject上运行它,它不会正确运行。我们从来没有回到主线程,NSLog(@“得到主线程”);从不出现,应用程序挂起。 BUT,(这是事情变得非常奇怪)—如果我在小项目上运行代码FirsT,然后在大项目上运行它,一切工作完美。只有当我在大项目上运行代码,首先,麻烦显示出来。

这里是踢球者,如果我把第二个调度行改为:

dispatch_async(dispatch_get_main_queue(),^{

(也就是说,使用异步而不是同步来分派块到主队列),一切都工作。完美。无论项目中的文件数量多少!

我有失去解释这种行为。任何帮助或提示测试下一步将不胜感激。

解决方法 这是与磁盘I / O和GCD相关的常见问题。基本上,GCD可能为每个文件生成一个线程,并且在某一点上,您有太多的线程以供系统在合理的时间内服务。

每次调用dispatch_async()并在该块中尝试任何I / O(例如,它看起来像是在这里读取一些文件),可能是该代码块正在执行的线程将阻塞(由 *** 作系统获得暂停),同时等待从文件系统读取数据。 GCD的工作方式是这样的,当它看到其中一个工作线程被阻塞在I / O上,你仍然要求它同时做更多的工作,它只会产生一个新的工作线程。因此,如果你尝试在并发队列上打开50个文件,很可能你最终会导致GCD产生〜50个线程。

这是太多的线程,系统有意义的服务,你最终饿死你的主线程的cpu。

解决这个问题的方法是使用串行队列而不是并发队列来进行基于文件的 *** 作。这很容易做到。您将需要创建一个串行队列并将其作为一个ivar存储在对象中,因此您最终不会创建多个连续队列。所以删除此调用:

dispatch_queue_t taskQ = dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAulT,0);

在你的init方法中添加:

taskQ = dispatch_queue_create(“com.yourcompany.yourMeaningfulLabel”,disPATCH_QUEUE_SERIAL);

将其添加到dealloc方法中:

dispatch_release(taskQ);

并在类声明中将它添加为一个ivar:

dispatch_queue_t taskQ;

总结

以上是内存溢出为你收集整理的objective-c-dispatch_sync与主队列上的dispatch_async全部内容,希望文章能够帮你解决objective-c-dispatch_sync与主队列上的dispatch_async所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1047646.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-25
下一篇2022-05-25

发表评论

登录后才能评论

评论列表(0条)

    保存