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

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(使用前将#替换为@)

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

  • 观察 UIDatePicker 的变化

    我注意到没有委托来观察 UIDatePicker 中的变化 有没有一种方法可以在不确认任何内容的情况下检测选择器中何时进行更改 例如它旋转并落在新数字上的那一刻 我希望能够检测到这一点 我考虑过关键值观察 但我不认为有一个属性会立即改变 您
  • xcode 4 垃圾收集已删除?

    我正在学习 Xcode 和 Objective C 但是我正在阅读的书使用的是旧版本 3 2 的 Xcode 其中一章完全致力于内存和泄漏 说我需要通过 项目设置 gt 构建 打开垃圾收集 但是 我找不到垃圾收集设置 它已被删除还是我只是错
  • 在 iOS4 中视图控制器即将弹出时收到通知

    这个问题以前有人问过 但我能找到的答案是 2009 年的 不适合我的问题 让我重申一下这个问题 我有一个UINavigationController产生并推动许多不同的UIViewControllers 入栈 其中之一涉及一些核心数据操作
  • 使用 WebRTC 构建 iOS 本机应用程序

    我找了4天了 还是没找到 我构建了所有库并将其集成到我的自定义项目中 但我不知道应该采取哪些步骤才能使其正常工作 我在代码示例 解释中发现的唯一内容是 tech appear in 2015 05 25 Getting started wi
  • UITextField 的自定义字体在编辑模式下发生变化

    我有一个UITextField这是从 xib 加载的 在它的视图控制器中viewDidLoad方法中 我将字体设置为自定义值 该值在 plist file和所有 它显示良好 除非处于编辑模式 此时字体从我的自定义字体切换为默认字体 我认为这
  • NSView 鼠标跟踪

    我在 Mac OS X 上遇到了 Cocoa NSView 的奇怪行为 我在 NSView 容器中有一个自定义 NSView 这个自定义 NSView 跟踪鼠标移动 点击 并有一个工具提示 当我在所描述的视图上方添加 NSView 时 即使
  • iOS设备和iPhone模拟器内存​​组织的差异

    我正在尝试使用 Xcode 4 3 3 和 iPhone 5 1 模拟器开发一个应用程序 当我在模拟器上运行这个应用程序时 我没有收到任何警告 并且它运行得很好 但是 当我尝试在 iOS 设备上执行此操作时 我收到一条警告消息 收到内存警告
  • 如何使用 iconutil 手动创建 icns 文件?

    当我验证我的应用程序时 出现此错误 应用程序包不包含 ICNS 格式的图标 同时包含512x512 and a 512x512 2x image 我用来制作 icns 图标Img2icns http www img2icnsapp com
  • 如何检测按下的返回键并使用 UIKeyInput 协议对其进行响应?

    我有一个表视图 显示我希望用户能够编辑的列表 为了节省空间 并且让我的视图更容易看清 我创建了一个符合 UIKeyInput 协议的自定义工具栏 这样我就可以拉起键盘而无需使用任何文本字段 到目前为止 一切都很好 我有一个可变字符串正在处理
  • 在 Cocoa Mac OSX 中设置 FirstResponder 时出现问题

    我正在开发一个小应用程序只是为了学习可可 并且我很难将 FirstResponder 设置为某些 NSTextFields 当视图打开时 我希望选择第一个 NSTextField clientNumber 因此我在 loadView 方法末
  • OS X Cocoa 自动布局隐藏元素

    我正在尝试使用新的自动布局 http developer apple com library mac documentation UserExperience Conceptual AutolayoutPG Articles Introdu
  • 自定义 UITableViewCell 错误

    我收到此错误 Terminating app due to uncaught exception NSUnknownKeyException reason
  • 当表格为空时 iPhone UITableView 图像背景

    我想当我的 UITableView 为空时显示图像背景 目前 我尝试将 UIImageView 添加到包含表格的视图控制器 但 XCode 不允许这样做 有没有好的方法呢 您可以在表视图顶部添加图像视图或更改表视图的背景视图 Check i
  • 如何将NSTextView的格式化内容转换为字符串

    我需要将 NSTextView 的内容从 Mac 应用程序传输到 iOS 应用程序 我使用 XML 作为传输文件格式 所以我需要将 NSTextView 的内容 文本 字体 颜色等 保存为字符串 有什么办法可以做到这一点吗 一种方法是存档
  • 如何使用 MonoTouch 在 UIKeyboard 之上添加 UIToolbar?

    我按照 Obj C 中的示例进行操作定制 iPhone 键盘 https stackoverflow com questions 1610542 custom iphone keyboard 1612549 1612549但是 为了在 Wi
  • 应用程序仅启用纵向,但 UIImagePickerController 在 iOS6 中旋转

    请注意 下面的答案 不适用于 iOS6 所以我仍然需要答案 我的应用程序仅启用纵向模式 但是 如果我将 UIImagePickerController 作为子视图嵌入其中 并旋转设备 则顶部和底部栏将保持在同一位置 但 UIImagePic
  • 使用 MPMoviePlayerViewController 时的 iPad 旋转错误

    问题摘要 使用 MPMoviePlayerViewController 播放视频时更改 iPad 设备或模拟器的方向会导致视频播放器关闭时旋转状态不一致 这是 iPad SDK 3 2 中的一个已知错误 记录于http www openra
  • 共享扩展程序未出现在能够在 iPhone 上共享照片的应用程序列表中

    我正在尝试创建一个共享应用程序扩展 并按照以下来源的教程进行操作 http www technetexperts com mobile share extension in ios application overview with exa
  • iOS 11 中的密码自动填充快速输入栏

    iOS 11 中引入了一项新功能 应用程序密码自动填充 此功能允许用户直接从键盘快速输入栏使用其应用程序中保存的密码 https techcrunch com 2017 06 08 ios 11s new password autofill
  • 如何删除以前的 ViewController

    我是一名学生 对编程还很陌生 我正在尝试在业余时间学习 Objective C Swift 我使用 spriteKit 和 swift 制作了一个游戏 有多个菜单 场景 我正在尝试从一个视图控制器转换到另一个视图控制器 为此 我使用了以下代

随机推荐