Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 如何正确显示";“进展”;在使用Grand Central Dispatch处理某件事情时,是否以MODALY方式创建工作表?_Objective C_Cocoa_Grand Central Dispatch - Fatal编程技术网

Objective c 如何正确显示";“进展”;在使用Grand Central Dispatch处理某件事情时,是否以MODALY方式创建工作表?

Objective c 如何正确显示";“进展”;在使用Grand Central Dispatch处理某件事情时,是否以MODALY方式创建工作表?,objective-c,cocoa,grand-central-dispatch,Objective C,Cocoa,Grand Central Dispatch,我试图在包含单个进度条的窗口上显示一个工作表,以显示使用Grand Central Dispatch异步运行的某个长函数的进度。我几乎已经找到了它,但无法使工作表显示在焦点位置,可能是因为我没有使用runModalForWindow:或类似工具 这大概就是我目前正在做的,它是由于按下主窗口上的按钮而发生的: // Prepare sheet and show it... [NSApp beginSheet:progressSheet modalForWindow:window

我试图在包含单个进度条的窗口上显示一个工作表,以显示使用Grand Central Dispatch异步运行的某个长函数的进度。我几乎已经找到了它,但无法使工作表显示在焦点位置,可能是因为我没有使用
runModalForWindow:
或类似工具

这大概就是我目前正在做的,它是由于按下主窗口上的按钮而发生的:

    // Prepare sheet and show it...

    [NSApp beginSheet:progressSheet modalForWindow:window modalDelegate:nil didEndSelector:NULL contextInfo:NULL];

    [progressSheet makeKeyAndOrderFront:self];

    [progressBar setIndeterminate:NO];
    [progressBar setDoubleValue:0.f];
    [progressBar startAnimation:self];


    // Start computation using GCD...

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        for (int i = 0; i < 1000; i ++) {
            // Do some large computation here
            // ...

            // Update the progress bar which is in the sheet:
            dispatch_async(dispatch_get_main_queue(), ^{
                [progressBar setDoubleValue:(double)i];
            });
        }


        // Calculation finished, remove sheet on main thread

        dispatch_async(dispatch_get_main_queue(), ^{
            [progressBar setIndeterminate:YES];

            [NSApp endSheet:progressSheet];
            [progressSheet orderOut:self];
        });
    });
//准备工作表并显示它。。。
[NSApp beginSheet:progressSheet modalForWindow:window modalDelegate:nil DiEndSelector:NULL上下文信息:NULL];
[progressSheet MakeKeyandDerfront:self];
[进度条设置不确定:否];
[progressBar setDoubleValue:0.f];
[progressBar startAnimation:self];
//使用GCD开始计算。。。
调度异步(调度获取全局队列(0,0)^{
对于(int i=0;i<1000;i++){
//在这里做一些大型计算
// ...
//更新工作表中的进度条:
dispatch\u async(dispatch\u get\u main\u queue()^{
[progressBar setDoubleValue:(double)i];
});
}
//计算完成,移除主螺纹上的薄板
dispatch\u async(dispatch\u get\u main\u queue()^{
[进度条设置不确定:是];
[NSApp尾页:进度页];
[progressSheet orderOut:self];
});
});
这是可行的,除了主窗口仍处于焦点、工作表失焦以及进度条没有动画(除非我在其上使用
setUseSThreadAnimation:YES


我想我遇到的问题是,在开始异步计算之前,我不确定如何在不阻塞主线程的情况下以模式运行工作表?

正如Brad所说,它应该可以工作

为了进行快速测试,我以编程方式创建了一个工作表(通常,您可能会使用nib文件,但它们很难粘贴到此文本中)。如果我从普通Cocoa窗口中的按钮调用下面的代码,它将按预期工作。请注意,工作表上的文本字段是first responder,如果在键盘打开时键入,它将接受输入

#define maxloop 1000

- (IBAction)startTask:(id)sender
{
    // Prepare sheet and show it...

    breakLoop = NO;

    NSRect sheetRect = NSMakeRect(0, 0, 400, 114);

    NSWindow *progSheet = [[NSWindow alloc] initWithContentRect:sheetRect 
                                                      styleMask:NSTitledWindowMask 
                                                        backing:NSBackingStoreBuffered 
                                                          defer:YES];

    NSView *contentView = [[NSView alloc] initWithFrame:sheetRect];

    NSProgressIndicator *progInd = [[NSProgressIndicator alloc] initWithFrame:NSMakeRect(143, 74, 239, 20)];

    NSTextField *inputField = [[NSTextField alloc] initWithFrame:NSMakeRect(145, 48, 235, 22)];

    NSButton *cancelButton = [[NSButton alloc] initWithFrame:NSMakeRect(304, 12, 82, 32)];
    cancelButton.bezelStyle = NSRoundedBezelStyle;
    cancelButton.title = @"Cancel";
    cancelButton.action = @selector(cancelTask:);
    cancelButton.target = self;

    [contentView addSubview:progInd];
    [contentView addSubview:inputField];
    [contentView addSubview:cancelButton];

    [progSheet setContentView:contentView];


    [NSApp beginSheet:progSheet 
       modalForWindow:self.window 
        modalDelegate:nil 
       didEndSelector:NULL 
          contextInfo:NULL];

    [progSheet makeKeyAndOrderFront:self];

    [progInd setIndeterminate:NO];
    [progInd setDoubleValue:0.f];
    [progInd startAnimation:self];


    // Start computation using GCD...

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        for (int i = 0; i < maxloop; i++) {

            [NSThread sleepForTimeInterval:0.01];

            if (breakLoop) 
            {
                break;
            }

            // Update the progress bar which is in the sheet:
            dispatch_async(dispatch_get_main_queue(), ^{
                [progInd setDoubleValue: (double)i/maxloop * 100];
            });
        }


        // Calculation finished, remove sheet on main thread

        dispatch_async(dispatch_get_main_queue(), ^{
            [progInd setIndeterminate:YES];

            [NSApp endSheet:progSheet];
            [progSheet orderOut:self];
        });
    });
}

- (IBAction)cancelTask:(id)sender 
{
    NSLog(@"Cancelling");
    breakLoop = YES;
}
#定义maxloop 1000
-(iAction)startTask:(id)发送方
{
//准备表格并展示它。。。
breakLoop=NO;
NSRect sheetRect=NSMakeRect(0,0,400,114);
NSWindow*程序表=[[NSWindow alloc]initWithContentRect:sheetRect
样式掩码:NSTitledWindowMask
backing:NSBackingStoreBuffered
延期:是];
NSView*contentView=[[NSView alloc]initWithFrame:sheetRect];
NSPROGESSINDICATOR*progInd=[[NSPROGESSINDICATOR alloc]initWithFrame:NSMakeRect(143,74,239,20)];
NSTextField*inputField=[[NSTextField alloc]initWithFrame:NSMakeRect(145,48,235,22)];
NSButton*cancelButton=[[NSButton alloc]initWithFrame:NSMakeRect(304,12,82,32)];
cancelButton.bezelStyle=NSRoundedBezelStyle;
cancelButton.title=@“取消”;
cancelButton.action=@选择器(cancelTask:);
cancelButton.target=self;
[contentView addSubview:progInd];
[contentView addSubview:inputField];
[内容视图添加子视图:取消按钮];
[progSheet setContentView:contentView];
[NSApp开始页:程序页
modalForWindow:self.window
莫代尔德莱盖特:零
DiEndSelector:空
contextInfo:NULL];
[程序表MakeKeyandDerfront:self];
[progInd SetUndeterminate:否];
[progInd setDoubleValue:0.f];
[progInd startAnimation:self];
//使用GCD开始计算。。。
调度异步(调度获取全局队列(0,0)^{
对于(int i=0;i

为难看的表单道歉,但除此之外,此代码按预期工作,因此您看到的问题可能与GCD无关。

我遇到了完全相同的问题。经过反复试验,我找到了解决办法。确保工作表的窗口是(a)NSWindow而不是NSPanel(这可能无关紧要),并且该窗口不会显示标题栏(因为它是您正在使用的工作表)


出于这个原因,我关闭了标题栏,但不知何故,它是正确实现焦点所必需的。勾选标题栏复选框将显示我的进度条工作表焦点。

为窗口模式运行工作表不应阻止主线程(否则,将不会执行方法开头的
-beginSheet:
位之后的任何内容)。我在这里的应用程序中使用了与此几乎相同的东西(模式表和您一样显示,上面有一个进度条),并且它在后台运行GCD块时可以很好地进行更新。工作表向下滑动的窗口上的控件变灰,表示该窗口对工作表失去了焦点,因此这看起来也很正常。在主线程上是否还有其他东西在排队等待大量操作?@BradLarson我能想到的唯一可能导致问题的另一件事是作为主计算一部分的
dispatch\u apply
,但是