通过在主队列上执行的块更新NSProgressIndicator时的CoreAnimation警告

时间:2015-04-24 20:01:29

标签: macos cocoa core-animation nsoperationqueue nsprogressindicator

我有以下方案将Core Data实体导出为JSON并在执行此操作时显示进度条。

有时,在导出完成后取消带有进度条的工作表后,我会收到以下警告作为控制台消息:

  

CoreAnimation:警告,删除线程与未提交的CATransaction;   在环境中设置CA_DEBUG_TRANSACTIONS = 1以记录回溯。

AppDelegate.m

//  AppDelegate.m

- (void)exportAsJSON:(id)sender;
{
    NSSavePanel *savePanel = [NSSavePanel savePanel];

    [savePanel beginSheetModalForWindow:[self window] completionHandler:^(NSInteger result) {
        WMJSONExportOperation *operation = nil;

        if (result == NSFileHandlingPanelOKButton)
        {
            [_progressIndicator setDoubleValue:0];
            operation = [[WMJSONExportOperation alloc] init];

            // setProgressCallbackBlock
            [operation setProgressCallbackBlock: ^(double progress) {
                [[NSOperationQueue mainQueue] addOperationWithBlock:^
                 {
                     [_progressIndicator setDoubleValue: progress];
                 }];
            }];

            // setExportCompletionBlock
            [operation setExportCompletionBlock:^(NSData *data, NSError *error) {
                // Insert code here to save data to disk
                [_window endSheet:_exportProgressSheet];
            }];

            [_window beginSheet:_exportProgressSheet completionHandler:^(NSInteger result) {
                NSLog(@"ExportProgressSheet completionHandler executed");
            }];

            NSOperationQueue *queue;
            queue = [[NSOperationQueue alloc] init];
            [queue addOperation:operation];
        }

    }];
}

WMJSONExportOperation.m,NSOperation的子类:

- (void)main;
{
    NSError *error = nil;
    NSData *data = nil;

    // just for illustrating the problem:
    for (int i=1; i<=10; i++) {
        sleep(1);
        [self progressCallbackBlock](i * 10);
    }

    [self exportCompletionBlock](data, error);
}

@end

所以第一个问题是:它只是一个警告,我应该关心吗?

第二个问题是,如何避免警告。有关于描述类似问题的SO的问题,但建议的解决方案通常只是从主队列操作NSProgressIndicator。这不是我正在使用此代码做的事情:

    // setProgressCallbackBlock
    [operation setProgressCallbackBlock: ^(double progress) {
        [[NSOperationQueue mainQueue] addOperationWithBlock:^
         {
             [_progressIndicator setDoubleValue: progress];
         }];
    }];

1 个答案:

答案 0 :(得分:0)

setting the CA_DEBUG_TRANSACTIONS environment variable进一步调查消息之后,我发现,问题不是发送给NSProgressIndicator的消息,而是关闭了表单,我确实触发了另一个队列而不是主要队列。

所以这个改变解决了我的问题:

[_window endSheet:_exportProgressSheet];

变为:

[[NSOperationQueue mainQueue] addOperationWithBlock:^
   {
      [_window endSheet:_exportProgressSheet];
   }];