3

Apple 引入了 Activity Tracing 来支持调试异步代码。我在正确使用它时遇到了一些困难。我的示例场景是一个小型 MacOS 应用程序,它只是下载一个文件:

- (IBAction)actionDownload:(NSButton *)sender {

    os_activity_label_useraction("actionDownload");
    os_log_t logDemo = os_log_create("ActivityTracingDemo", "demo");

    os_log_debug(logDemo, "actionDownload start (1)");

    os_activity_t actTop = os_activity_create(
        "HTTP Download",
        OS_ACTIVITY_NONE,
        OS_ACTIVITY_FLAG_DETACHED);

    os_activity_apply(actTop, ^{

        os_log_debug(logDemo, "actionDownload start");

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
                                     (int64_t)(2 * NSEC_PER_SEC)),
                       dispatch_get_main_queue(), ^{
                           os_log_debug(logDemo,
                                        "actionDownload two second later");
                       });

        NSURL *url = [NSURL URLWithString:
                      @"https://www.google.de/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"];

        // Get the current activity (or create a new one,
        // if no current activity exists):
        os_activity_t act = os_activity_create(
            "HTTP Response",
            OS_ACTIVITY_CURRENT,
            OS_ACTIVITY_FLAG_IF_NONE_PRESENT);

        NSURLSessionDownloadTask *downloadPhotoTask =
            [ [NSURLSession sharedSession]
              downloadTaskWithURL:url
              completionHandler:^(NSURL *location,
                                  NSURLResponse *response,
                                  NSError *error)
             {
                 os_activity_apply(act, ^{
                     // Now the same activity is active,
                     // that initiated the download.
                     os_log_debug(logDemo, "actionDownload received data (restored activity)");
                 });
                 os_log_debug(logDemo, "actionDownload received data");
             }];
        [downloadPhotoTask resume];
    });
}

过滤我Console.app收到的消息:

控制台消息

显然NSURLSession不会调用completionHandler与启动下载相同的活动。我必须在回调中手动应用该活动。有一个更好的方法吗?我认为活动旨在跨流程跟踪事物。在这种情况下,如果不做一些额外的工作,它甚至不能在同一个进程中工作。

Console.app我得到的活动视图中:

控制台活动

树视图看起来很有希望,可以快速了解触发了哪些应用场景。最初我认为没有必要在操作回调中应用新活动,而是可以使用它os_activity_label_useraction来让场景显示在Console.app顶级活动视图中。显然情况并非如此。我在任何日志中都找不到该标签。

我的解决方案是在actionDownload. Console.app此活动在活动视图的顶层可见。我不喜欢这个解决方案有两点:

首先,我必须明确地创建一个具有新范围的新活动。这给源代码增加了很多噪音。我的项目中有许多非常简短的操作方法。如果没有这个,消息视图也可以工作。在那里,我只是通过过滤子系统、类别和活动 ID 来获得我感兴趣的内容。

其次,与启动活动的连接丢失。

获得有关如何正确使用活动跟踪,尤其是层次结构的一些提示会很棒。

4

0 回答 0