如何安排一个块在下一次运行循环迭代中运行?

2024-01-09

我希望能够执行block在下一次运行循环迭代中。它是在下一个运行循环的开始还是结束时执行并不那么重要,只是执行会推迟到当前运行循环中的所有代码都完成执行为止。

我知道以下内容不起作用,因为它与主运行循环交错,因此我的代码可能会在下一个运行循环上执行,但也可能不会。

dispatch_async(dispatch_get_main_queue(),^{
    //my code
});

我相信以下内容也遇到了与上面相同的问题:

dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), ^(void){
    //my code
});

Now I believe以下内容将起作用,因为它被放置在当前运行循环的末尾(如果我错了,请纠正我),这实际上会起作用吗?

[self performSelector:@selector(myMethod) withObject:nil afterDelay:0];

带有一个定时器怎么样?0间隔?文档指出:If seconds is less than or equal to 0.0, this method chooses the nonnegative value of 0.1 milliseconds instead.这是否意味着保证下一次运行循环迭代的执行?

[NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(myMethod) userInfo:nil repeats:NO];

这就是我能想到的所有选项,但我仍然距离在下一次运行循环迭代中执行块(而不是调用方法)更近,并保证它不会更快。


您可能不知道运行循环在每次迭代中所做的一切。 (在我研究这个答案之前我不是!)碰巧的是,CFRunLoop是的一部分开源 CoreFoundation 包 http://opensource.apple.com/source/CF/CF-744.12/,所以我们可以看看它到底意味着什么。运行循环大致如下所示:

while (true) {
    Call kCFRunLoopBeforeTimers observer callbacks;
    Call kCFRunLoopBeforeSources observer callbacks;
    Perform blocks queued by CFRunLoopPerformBlock;
    Call the callback of each version 0 CFRunLoopSource that has been signalled;
    if (any version 0 source callbacks were called) {
        Perform blocks newly queued by CFRunLoopPerformBlock;
    }
    if (I didn't drain the main queue on the last iteration
        AND the main queue has any blocks waiting)
    {
        while (main queue has blocks) {
            perform the next block on the main queue
        }
    } else {
        Call kCFRunLoopBeforeWaiting observer callbacks;
        Wait for a CFRunLoopSource to be signalled
          OR for a timer to fire
          OR for a block to be added to the main queue;
        Call kCFRunLoopAfterWaiting observer callbacks;
        if (the event was a timer) {
            call CFRunLoopTimer callbacks for timers that should have fired by now
        } else if (event was a block arriving on the main queue) {
            while (main queue has blocks) {
                perform the next block on the main queue
            }
        } else {
            look up the version 1 CFRunLoopSource for the event
            if (I found a version 1 source) {
                call the source's callback
            }
        }
    }
    Perform blocks queued by CFRunLoopPerformBlock;
}

您可以看到有多种方法可以挂钩运行循环。您可以创建一个CFRunLoopObserver被要求参加您想要的任何“活动”。您可以创建版本 0CFRunLoopSource并立即发出信号。您可以创建一对连接的CFMessagePorts,将一个包装在版本 1 中CFRunLoopSource,并向其发送消息。您可以创建一个CFRunLoopTimer。您可以使用以下任一方法对块进行排队dispatch_get_main_queue or CFRunLoopPerformBlock.

您需要根据调度块的时间以及需要调用它的时间来决定使用哪些 API。

例如,触摸是在版本 1 源中处理的,但如果您通过更新屏幕来处理触摸,则在提交核心动画事务之前不会实际执行该更新,这发生在kCFRunLoopBeforeWaiting观察者。

现在假设您想要在处理触摸时调度该块,但希望它在事务提交后执行。

您可以添加自己的CFRunLoopObserver为了kCFRunLoopBeforeWaiting活动,但该观察者可能在 Core Animation 的观察者之前或之后运行,具体取决于您指定的顺序和 Core Animation 指定的顺序。 (核心动画当前指定的顺序为 2000000,但没有记录,因此可能会更改。)

确保您的块在 Core Animation 的观察者之后运行,即使您的观察者运行before核心动画的观察者,不要直接在观察者的回调中调用该块。相反,使用dispatch_async此时将块添加到主队列中。将块放入主队列将强制运行循环立即从“等待”中唤醒。它将运行任何kCFRunLoopAfterWaiting观察者,然后它将耗尽主队列,此时它将运行您的块。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何安排一个块在下一次运行循环迭代中运行? 的相关文章

  • 如何自定义 NSSlider

    我正在尝试在 Cocoa 中实现一个具有 5 个值的自定义滑块 查看我的演示项目 可以在此处下载 http s000 tinyupload com index php file id 07311576247413689572 http s0
  • 在 UITableView 中设置滚动位置

    我有一个应用程序 其工作方式与 iPhone 的 联系人 应用程序的工作方式有些相似 当我们添加新的联系人时 用户将被定向到包含联系人信息的仅查看屏幕 如果我们从导航栏中选择 所有联系人 用户将导航到查看最近添加的联系人的所有联系人列表 我
  • 使用 Nib 实现国际化。这真的是个好主意吗?

    在苹果文档中 他们说笔尖只需将笔尖翻译成多种语言即可实现国际化 我现在正在考虑一个更糟糕但现实的场景 你已经制作了一个巨大的用户界面 然后你将其翻译成 25 种语言 所以你会得到 25 个不同的笔尖 您还会在样式和定义 UI 方面获得巨大的
  • 在 Objective C 中使用下划线作为属性名称前缀 [重复]

    这个问题在这里已经有答案了 我以前避免在变量名中使用下划线 这可能是我大学 Java 时代的遗留下来的 因此 当我在 Objective C 中定义属性时 我自然会这样做 In the header interface Whatever N
  • Objective-C 实例变量?

    我确信我在这里的困惑只是因为陷入 Java 思维方式 并且不理解 Obj C 在这种情况下有何不同 在Java中 我可以在类中声明一个变量 就像这样 并且每个instance该类的 将会有它自己的 MyClass String myVar
  • iOS:弃用 AudioSessionInitialize 和 AudioSessionSetProperty

    我对 Objective C 很陌生 正在尝试更新一些大约 3 年前的代码以与 iOS 7 一起使用 有两两个实例AudioSessionSetProperty and AudioSessionInitialize出现在代码中 1 void
  • 使用 Push Transition 效果更改 RootViewcontroller

    在我的iOS应用程序中 我需要更改应用程序之间窗口的rootviewController 因此 当我动态更改我的rootviewcontroller时 它会在更改之前轻拂视图 但我想要的是在更改rootviewcontroller时提供平滑
  • iOS:从非图像数据生成图像(Godus,如风景)

    所以看到图像后Godus http www kickstarter com projects 22cans project godus我想知道如何生成简单的 非交互式的 2D 图像 with 不同高度或层数的颜色不同就像下面的图片一样 我只
  • 在 iOS 中录制音频并永久保存

    我制作了 2 个 iPhone 应用程序 可以录制音频并将其保存到文件中并再次播放 其中之一使用 AVAudiorecorder 和 AVAudioplayer 第二个是苹果的在这里说话 http developer apple com l
  • iPhone 标签栏上的未读计数

    在 Cocoa Touch 上实现 TabBar 上图标的未读计数的最佳方法是什么 我想模仿 SMS 或邮件应用程序的行为 向我的应用程序的用户显示未读消息计数 并使用包含数字的红点 您正在寻找的属性称为徽章 您可以通过执行以下操作来设置它
  • 从 NSError 返回 NSString

    我正在使用NSURLRequest我的 iPhone 应用程序中的类 调用它的方法返回一个NSString这对于连接正常时非常有用 但问题是我需要将 NSError 转换为 NSString 以便我可以将其返回或运行一些if 对此的声明 有
  • Objective-c中的贝塞尔曲线算法

    比我聪明的人可以看一下这个吗 我正在尝试实现我发现的贝塞尔曲线算法here http webtweakers com swag GRAPHICS 0074 PAS html在 Objective c 中 输出是错误的 我想我正确地转换了代码
  • 无边框 NSButton 单击时变为灰色

    我正在使用三个带有图像集的 NSButton 制作一个小应用程序 这些按钮没有边框也没有背景 但是 当我单击按钮时 它会变成灰色矩形 我怎样才能解决这个问题 谢谢 让你的按钮类型为NSMomentaryChangeButton myBtn
  • 访问iOS 7隐藏的UITableViewCellScrollView?

    苹果改变了UITableViewCelliOS 7 中的层次结构 使用iOS 6 1 SDK
  • OpenGL ES 1.1 顶点缓冲区对象不工作

    我正在使用 OpenGL ES 1 1 开发一款 iPhone 游戏 需要使用顶点缓冲区对象来渲染 500 多个粒子而不降低性能 我的游戏能够使用非 VBO 方法成功绘制 但现在我尝试合并 VBO 却不再绘制任何内容 请帮助我找出我做错了什
  • 如何确定 UINavigationController 中工具栏的高度?

    我有一个带有由 UINavigationController 呈现的工具栏的视图 当我处理 UIKeyboardWillShowNotification 时 我将整个屏幕向上滚动键盘的高度 问题是当显示键盘时 底部工具栏不显示 所以我只需将
  • NSSortDescriptor 和多对多关系

    我有两种反对意见 地点和历史项目 我正在尝试获取附加到任何历史记录项目的位置 因此该位置的获取谓词是 history count gt 0 效果很好 我还想使用 NSSortDescriptor 按最新历史项目的日期对位置对象进行排序 据我
  • iPhone 上的锁定方向 UIWebView

    有没有办法锁定 UIWebView 的方向 使用 Obj C JS 还是 Html 我不想有按钮或任何东西 我只想在应用程序打开时将其锁定为纵向 好像这个堆栈溢出帖子 https stackoverflow com questions 43
  • 在 iPhone 模拟器中从硬盘读取文件

    是否可以将文件 从我的普通文件系统 读入在 iPhone 模拟器上运行的 iPhone 应用程序 据我所知 iPhone 本身没有 用户可访问的 文件系统 但这只是为了测试 并且只能在模拟器中运行 该文件将是一个可以在应用程序运行时编辑的文
  • NSUserDefaults、Settings.bundle 和应用程序组

    我有一个有 2 个目标的应用程序 主应用程序和 Today 扩展 为了在这些目标之间共享设置 我打开了应用程序组功能 添加了一个组group myApp com然后使用NSUserDefaults在主应用程序和今日扩展中都是如此 var d

随机推荐