我正在尝试通过NSOpenPanel处理用户加载的文件,然后启动一个模式会话,以便在我的自定义窗口类上显示进度。在最初的几十次尝试中,它运行得很好,直到我开始遇到随机的碰撞。我分配的所有对象都是在每次迭代之后释放的,所以我有点困惑如何从这里开始。以下是后代的代码片段:
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调用的按钮。我希望有人能给我指明正确的方向。谢谢大家的欢呼声。
发布于 2018-10-17 21:47:25
在启用僵尸的情况下运行,以缩小崩溃原因。编辑方案..。诊断..。僵尸对象复选框)
发生在我身上的是,当endModalSession被递归调用时,它崩溃了。不知道是什么导致了你的问题。
以下是我遇到的一些(可能是无关的)问题:
以下是一些源代码FWIW
- (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];https://stackoverflow.com/questions/52827579
复制相似问题