NSView拖动操作错误

时间:2012-07-28 20:47:58

标签: macos cocoa encoding drag-and-drop nsview

我在OS X上用Cocoa进行编码。

我正在尝试接收一个拖放到我的NSView子类上的文件 - 我可以这样做;并且获取其内容和文件名并显示 - 我可以为任何类型的文件第一次执行此操作,但是第二次,当我尝试拖动时另一个文件,我只能设置标题setTitle:,而不是主体文字setText:

我得到的错误是:

  

取消拖动,因为在拖动会话期间引发了异常'NSInternalInconsistencyException'(原因'无效参数不满足:aString!= nil')

  

断言失败 - [NSTextFieldCell _objectValue:forString:errorDescription:],/ SourceCache / AppKit / AppKit-1187 / AppKit.subproj / NSCell.m:1532

我的代码(抱歉,这很长!):

- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
NSPasteboard *pboard;
NSDragOperation sourceDragMask;

sourceDragMask = [sender draggingSourceOperationMask];
pboard = [sender draggingPasteboard];

if ([[pboard types] containsObject:NSFilenamesPboardType]) {

    NSURL *file = [NSURL URLFromPasteboard:pboard];
    //NSData *data = [NSData dataWithContentsOfURL:file];

    NSError *error;
    NSStringEncoding encoding;
    NSString *contentString = [[NSString alloc] initWithContentsOfURL:file usedEncoding:&encoding error:&error];

    NSLog(@"Error: %@",error);

    NSString *last = [[file path] lastPathComponent];
    NSArray *parts = [last componentsSeparatedByString:@"."];
    NSString *filename = [parts objectAtIndex:0];
    NSString *fileType = [parts objectAtIndex:1];

    NSLog(@"FILETYPE: %@", fileType);

    if ([fileType isEqualToString:@"txt"] || [fileType isEqualToString:@"md"]) {
        [self setTitle:filename];

        if (self.textViewString == (id)[NSNull null] || self.textViewString.length == 0) {
            [self setText:contentString];
        } else {
            BOOL whatToDo = (NSRunCriticalAlertPanel(@"What do you want to do?", nil, @"Append", @"Replace", nil) == NSAlertDefaultReturn);

            if (whatToDo) {
                //Append
                [self setText:[NSString stringWithFormat:@"%@\n%@",self.textViewString,contentString]];
            } else {
                //Replace
                [self setText:contentString];
            }
        }
        return YES;
    } else {
        return NO;
    }
} else if ([[pboard types] containsObject:NSPasteboardTypeString]) {
    NSString *draggedString = [pboard stringForType:NSPasteboardTypeString];

    if (self.textViewString == (id)[NSNull null] || self.textViewString.length == 0) {
        [self setText:draggedString];
    } else {
        [self setText:[NSString stringWithFormat:@"%@\n%@",self.textViewString,draggedString]];
    }
    return YES;
}
else {
    return NO;
}

}

提前致谢! :)

2 个答案:

答案 0 :(得分:2)

听起来像Cocoa在引发任何异常时都会取消拖动,并且当内部需要字符串并且正在获得nil值时会引发异常。

只是猜测没有更多的信息,但我会预测stringWithFormat:正在引发异常,因为它看起来像你所写的唯一真正潜在的脆弱部分。

你正在做一些不明智的事情。首先,您假设-initWithContentsOfURL:usedEncoding:error:正在成功。你不应该这样做。相反,您需要传递可以填写错误的NSError **,测试contentString是否为零,如果是,请相应地检查error。我觉得你会发现你得到nilerror会解释原因。

可能不相关,但你的if (whatToDo)并没有做你想象的那样。由于whatToDo是指向自动释放的NSNumber实例的指针,因此指针非零,因此条件将始终计算为true。您可能要做的事情如下:

 BOOL whatToDo = (NSRunCriticalAlertPanel(@"What do you want to do?", nil, @"Append", @"Replace", nil) == NSAlertDefaultReturn);

    if (whatToDo) {
        //Append
        [self setText:[NSString stringWithFormat:@"%@\n%@",self.textViewString,contentString]];
    } else {
        //Replace

        [self setText:contentString];
    }

答案 1 :(得分:0)

非常感谢来自this answer by Conrad Shultz的许多提示和建议!我遵循了那里的建议和提示。

但是,我的问题变得非常非常基本。它在BOOL whatToDo = (NSRunCriticalAlertPanel(@"What do you want to do?", nil, @"Append", @"Replace", nil) == NSAlertDefaultReturn);

行中撒谎

事实证明字符串必须传递给第二个参数,但我传递了nil。固定!