【问题标题】:Checking if NSOpenPanel returns a directory检查 NSOpenPanel 是否返回目录
【发布时间】:2014-01-08 15:16:35
【问题描述】:

试图确定 NSOpenPanel 是否返回了文件或目录

我已将 Apple 的示例代码用于 fileExistsAtPath:,它适用于 fontPath 但似乎不适用于openpanel 不确定从 NSURL 获取 NSString 是否正确 - 我仍然是 Cocoa 新手

它确实表明存在语义问题 将 'const BOOL *' (aka 'const signed char *') 发送到 'BOOL *' (aka 'signed char *') 类型的参数会丢弃限定符

请帮忙

- (IBAction)openImage: (id)sender
{
    // present open panel...

NSString *    extensions = @"tiff/tif/TIFF/TIF/jpg/jpeg/JPG/JPEG/CR2";
NSArray *     types = [extensions pathComponents];
NSFileManager *fileManager = [[NSFileManager alloc] init];

//===================================
// example just to see if it works!!
NSArray *subpaths;   
BOOL isDir;
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSLibraryDirectory, NSUserDomainMask, YES);
if ([paths count] == 1) {
    NSString *fontPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Fonts"];
    if ([fileManager fileExistsAtPath:fontPath isDirectory:&isDir] && isDir) {
        NSLog(@"======= fontPath = %@", fontPath);          
    }
}
//============================================

// Let the user choose an output file, then start the process of writing samples
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel setAllowedFileTypes:types];
[openPanel setCanSelectHiddenExtension:YES];
[openPanel setCanChooseDirectories:YES];
[openPanel beginSheetModalForWindow:_window completionHandler:^(NSInteger result) {
    if (result == NSFileHandlingPanelOKButton)
    {
            // user did select an image...

        NSLog(@"URL = %@",[openPanel URL]);
        NSString *workFile = [[openPanel URL] absoluteString];
        NSLog(@"workFile %@",workFile);
        if ([fileManager fileExistsAtPath:workFile isDirectory:&isDir] && isDir) {
            NSLog(@"======== It's a dir=======");
        }


         [self openImageURL: [openPanel URL]];
        }
    }];
}

【问题讨论】:

  • fileExistsAtPath 将始终检查文件是否存在。因此,如果 fileExistsAtPath 返回 true,则可以在此处放置一个 else 条件,然后打印它是一个文件,否则在 else 条件下打印它是一个目录。

标签: cocoa


【解决方案1】:

当一个块引用在块本身之外声明的本地(堆栈)变量时:

  • 一个与局部变量相同类型和名称的常量被添加到块中;和

  • 该局部变量的当前用作块常量的值

这就是为什么当您尝试将块的常量isDir 的地址传递给预期非常量地址的地方时,您会收到引用const BOOL 的错误。

您可以将isDir 作为变量 传递给块,在其声明中使用__block 限定符,这意味着在块中使用isDir 完全是指与在块外声明的变量相同的变量

但是,从您的 cmets 看来,这似乎也不是您所需要的,而是您只希望在方法调用和 if 语句中使用块的本地变量。为此,只需在块中声明一个变量。您已经在块中声明了NSString *workFile,只需以相同的方式声明一个本地布尔值。

HTH

【讨论】:

    【解决方案2】:

    The __block Storage Type。您将对isDir 的引用传递给fileExistsAtPath:isDirectory:,它正在修改isDir 变量,并且isDir 变量被您作为completionHandler 传递的块复制。

    来自The __block Storage Type

    您可以指定导入的变量是可变的——也就是说, 读写——通过应用 __block 存储类型修饰符。

    【讨论】:

    • 谢谢,我可以看到问题与存在阻塞有关。已经阅读了一些关于块的文档,不能说我完全理解这个概念 - 这是我第一次真正尝试 Cocoa :} 我尝试声明 __block BOOL isDir;在各个地方,无济于事。我该怎么做?我只想显示一个 NSOpenPanel 如果用户选择一个文件然后打开它。如果他们选择一个目录,然后做其他事情。塔
    【解决方案3】:

    我想我现在明白了,谢谢大家。还认为 fileExistsAtPath 需要文件路径,因此必须使用 myUrl.path 转换 URL

    NSOpenPanel *openPanel = [NSOpenPanel openPanel];
    [openPanel setAllowedFileTypes:types];
    [openPanel setCanSelectHiddenExtension:YES];
    [openPanel setCanChooseDirectories:YES];
    [openPanel beginSheetModalForWindow:_window completionHandler:^(NSInteger result) {
        if (result == NSFileHandlingPanelOKButton)
        {
                // user did select an image...
                // get list of files in this dir
    
            NSURL *myUrl = [openPanel URL];
            NSString *workFile = myUrl.path;
            NSLog(@"workFile %@",workFile);
            BOOL isDir;
            if ([fileManager fileExistsAtPath:workFile isDirectory:&isDir] && isDir) {
                NSLog(@"---------It's a dir---");
    
            }
    
        }
    }];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-27
      • 2015-01-06
      • 1970-01-01
      • 2015-11-11
      • 2014-08-04
      • 2011-04-25
      • 2015-01-09
      相关资源
      最近更新 更多