【问题标题】:iOS Threading Violations Detection?iOS 线程违规检测?
【发布时间】:2012-08-23 18:36:32
【问题描述】:

在 iOS 上,我想知道是否有任何类似于 NSZombies 标志的东西可以设置为在需要主线程时从后台线程调用 API 时检测/引发。

对于块,似乎很容易陷入这样一种情况,即人们要么做出错误的假设,要么错误地判断哪个线程正在做什么。可以检测何时从错误线程进行调用的调试标志对于查找这些情况非常有用。

我主要关心的是 Apple 的框架(Cocoa Touch)。

提交了错误报告,#12180446。

【问题讨论】:

    标签: ios cocoa-touch objective-c-blocks concurrent-programming


    【解决方案1】:

    在需要在主线程上的任何 API 中使用以下内容:

    NSAssert([NSThread isMainThread], @"This must only be called on the main thread.");
    

    Apple 没有提供涵盖所有 UIKit 的东西。您需要在需要时调用它。

    【讨论】:

    • 是的,但是在打电话给他们之前由您来检查。没有可用的全局 UIKit 级断言。如果你认为你需要一个,你应该在 bugreport.apple.com 上打开一个雷达。他们不太可能添加它,因为它需要到处都有钩子(在最简单的实现中会产生运行时成本,并且在无成本实现中维护起来非常复杂)。但是您请求的方式是通过 bugreport.apple.com。同时,您可以在需要的地方添加此断言。
    • 我认为同样的论点可以用来反对支持像 NSZombies 这样的东西。 Apple 正在投入大量精力来增强开发人员工具并通过消除内存管理 (ARC)、细微的编码错误(静态分析器)、增强编译器消息等问题来降低标准。能够在调用时进行捕捉从后台线程到需要主线程的 API 将非常有用。苹果很聪明。我敢打赌,他们能想出一个不繁琐的方法。
    • 确保在 openradar.appspot.com 上发布您的雷达,以便其他人可以上当。
    【解决方案2】:

    我会做一些更实际的事情。当我调用块时。我用自定义方法来做。

    + (void) ensureDispatchOfBlock:(dispatch_block_t) block onQueue:(dispatch_queue_t) queue  async:(BOOL) async{
        if (queue == nil || dispatch_get_current_queue() == queue){
            block();
        }
        else {
            if (async){
                dispatch_async(queue, block);
            }
            else {
                dispatch_sync(queue, block);
            }
        }
    }
    
    
    + (void) ensureDispatchOnMainThread:(dispatch_block_t) block async:(BOOL) async{
        [self ensureDispatchOfBlock:block onQueue:dispatch_get_main_queue() async:async];
    }
    

    这使我能够“确保”正在提供的块的调度将发生在预期的块上。

    请记住非常谨慎地使用async:NO

    【讨论】:

      猜你喜欢
      • 2020-02-08
      • 1970-01-01
      • 2015-04-29
      • 1970-01-01
      • 1970-01-01
      • 2020-11-04
      • 2018-04-23
      • 2022-09-23
      • 1970-01-01
      相关资源
      最近更新 更多