首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSApplication -runModalSession坠机

NSApplication -runModalSession坠机
EN

Stack Overflow用户
提问于 2018-10-16 03:28:48
回答 1查看 476关注 0票数 0

我正在尝试通过NSOpenPanel处理用户加载的文件,然后启动一个模式会话,以便在我的自定义窗口类上显示进度。在最初的几十次尝试中,它运行得很好,直到我开始遇到随机的碰撞。我分配的所有对象都是在每次迭代之后释放的,所以我有点困惑如何从这里开始。以下是后代的代码片段:

代码语言:javascript
复制
NSModalSession m = [[NSApplication sharedApplication] beginModalSessionForWindow:progWindow];

while(index < [validImageURLS count])
{
    // Check if user presses the stop track button in pop up window
    if([[NSApplication sharedApplication] runModalSession:m] != NSModalResponseContinue)
    {
        stopProcessing = YES;
        break;
    }

    NSURL* current = [validImageURLS objectAtIndex:index];
    CGImageSourceRef imgSrc = CGImageSourceCreateWithURL((__bridge CFURLRef)current, NULL);
    CGImageRef image = CGImageSourceCreateImageAtIndex(imgSrc, 0, NULL);
    size_t img_width = CGImageGetWidth(image);
    size_t img_height = CGImageGetHeight(image);
    size_t new_size = 0.0;

    if(img_width > img_height)
    {
        new_size = img_width;
    }
    else
    {
        new_size = img_height;
    }

    float aspectRatio = img_width / (float)img_height;

    if(img_width >= img_height)
    {
        img_width  = (int)(round(log2((int)img_width)));
        img_width  = (int)(pow(2.0, img_width));

        if(img_width > 256)
        {
            img_width  = 256;
        }

        img_height = (int)(img_width / aspectRatio);
    }
    else
    {
        img_height = (int)(round(log2((int)img_height)));
        img_height = (int)(pow(2.0, img_height));

        if(img_height > 256)
        {
            img_height = 256;
        }

        img_width  = (int)(img_height * aspectRatio);
    }

    new_size = (int)(round(log2((int)new_size)) + 1);
    new_size = (int)(pow(2.0, new_size));

    GLubyte* imgDataBuffer = new GLubyte[img_width * img_height * ATLAS_NUM_CHANNELS];
    memset(imgDataBuffer, 0, img_width * img_height * ATLAS_NUM_CHANNELS);

    CGColorSpaceRef tmpColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef imgContext = CGBitmapContextCreate(imgDataBuffer,
                                                    img_width,
                                                    img_height,
                                                    8,
                                                    img_width * 4,
                                                    tmpColorSpace,
                                                    kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);

    // Initialize bitmap context attributes
    CGContextSetBlendMode(imgContext, kCGBlendModeNormal);
    CGContextSetInterpolationQuality(imgContext, kCGInterpolationHigh);

    CGRect _c = CGRectMake(0.0, 0.0, img_width, img_height);

    CGContextDrawImage(imgContext, _c, image);

    //flip back
    CGImageRef drawnImg = CGBitmapContextCreateImage(imgContext);

    NSString* c_p = [current path];
    std::string www = std::string([c_p UTF8String]);

    NSString* c_img_name = [current lastPathComponent];
    std::string zzz = std::string([c_img_name UTF8String]);

    // Creating new input content to be put into to the input list
    // for BinPack2D to process later
    SquareContent mycontent(www);
    mycontent.img = drawnImg;

    inputContent += BinPack2D::Content<SquareContent>(mycontent,
                                                      BinPack2D::Coord(),
                                                      BinPack2D::Size((int)img_width, (int)img_height),
                                                      false);

    CGContextRelease(imgContext);
    CGColorSpaceRelease(tmpColorSpace);
    CGImageRelease(image);
    CFRelease(imgSrc);
    delete [] imgDataBuffer;


    // Update progress bar view in our pop up window
    [self UpdateTrackProgressAsync:@[[NSNumber numberWithDouble:index],
                                     [NSNumber numberWithDouble:(int)[validImageURLS count]]]];

    index++;
}

[[NSApplication sharedApplication] endModalSession:m];

下面是上述错误的屏幕截图:

我只是遵循苹果文档中提出的结构:https://developer.apple.com/documentation/appkit/nsapplication/1428590-runmodalsession?language=objc

我之所以需要通过窗口的模态会话来运行这个程序,而不是在后台队列中分配代码,是因为我正在为一个插件开发这个程序。我希望处理停止主机应用程序中的所有其他UI,直到工作完成,或者用户按下将触发stopModal调用的按钮。我希望有人能给我指明正确的方向。谢谢大家的欢呼声。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-17 21:47:25

在启用僵尸的情况下运行,以缩小崩溃原因。编辑方案..。诊断..。僵尸对象复选框)

发生在我身上的是,当endModalSession被递归调用时,它崩溃了。不知道是什么导致了你的问题。

以下是我遇到的一些(可能是无关的)问题:

  • 确保没有递归发生
  • 请参阅下面的endModalSession子函数,以避免递归调用
  • 确保您的应用程序是主应用程序,您的窗口是关键窗口。

以下是一些源代码FWIW

代码语言:javascript
复制
- (void)endModalSession
{
   if ( modalSession )
   {
      NSModalSession tempSession = modalSession;
      modalSession = NULL;
      [NSApp endModalSession:tempSession];
   }
   appInactiveWait = NO;
}

- (BOOL) waiting { return (modalSession || appInactiveWait); }

- (void)foo
{
   while ( !done )
   {
      // Only start a modal session when app is active.
      // Otherwise you get spurious Dock bouncing when you switch between Finder and this app.
      // Particulary, Remote afp mounts send spurious FSEventStream events every 30 seconds.
      if ( [NSApp isActive] && !startedModal )
      {
         if ( [NSApp keyWindow] == remoteFileManagerWindow || [NSApp keyWindow] == [NSApp mbWindow] )
         {
            startedModal = YES;
            //DLog( @"startingModal (RemoteFileManager) cookie %d", task.readWriteCookie );
            modalSession = [NSApp beginModalSessionForWindow:remoteFileManagerWindow];
            appInactiveWait = NO;
            //DLog( @"startedModal (RemoteFileManager) cookie %d", task.readWriteCookie );
         }
         else
         {
            DLog( @"deferring modal (RemoteFileManager) to keyWindow %@", [NSApp keyWindow] );
         }
      }

      if ( ![self waiting] )
         break;

      if (blah blah blah )
         done = true;

      if ( [self waiting] )
      {             
         if ( modalSession )
         {
            if ([NSApp runModalSession:modalSession] != NSModalResponseContinue)
               break;
         }
         else
         {
            [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
         }
      }

      [self processDelayedQueue];
   }
   [self setCurrentTask:nil];

   [self endModalSession];
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52827579

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档