2

我在 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;
}

}

提前致谢!:)

4

2 回答 2

2

听起来 Cocoa 在引发任何异常时会取消拖动,而当内部某些东西需要一个字符串并且正在获取一个nil值时,就会引发异常。

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

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

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

 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];
    }
于 2012-07-28T21:15:04.050 回答
0

非常感谢康拉德舒尔茨的这个答案提供的许多提示和建议!我已经遵循了那里的建议和提示。

然而,我的问题被证明是非常非常基本的。它躺在线上BOOL whatToDo = (NSRunCriticalAlertPanel(@"What do you want to do?", nil, @"Append", @"Replace", nil) == NSAlertDefaultReturn);

事实证明,必须将一个字符串传递给第二个参数,但我传递的是nil. 固定的!

于 2012-07-29T12:56:41.247 回答