【问题标题】:NSView Drag Operation ErrorNSView 拖动操作错误
【发布时间】:2012-07-28 20:47:57
【问题描述】:

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

}

提前致谢! :)

【问题讨论】:

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


    【解决方案1】:

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

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

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

    可能不相关,但您的 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];
        }
    

    【讨论】:

    • 非常感谢,whatToDo 段正是我的意思,我没有意识到。我传入了一个 NSError 和 NSLogged 它,但它显示为“(null)”,所以我认为没有错。我现在得到的行为是现在读取并显示任何文件,但是如果我再次尝试使用任何文件失败并且 NSLogs "Assertion failure in -[NSTextFieldCell _objectValue:forString:errorDescription:], /SourceCache/AppKit/AppKit -1187/AppKit.subproj/NSCell.m:1532"
    • 您能否发布更新后的代码,包括NSError 的更改和对whatToDo 的修复?想确保我们在同一个页面上。
    • self.textViewString == (id)[NSNull null] 想做什么?你的意思是self.textViewString == nil
    • 尝试检查字符串是否为空或null,我在this Stack overflow answer中捡到了。
    • 不适合这种情况。在 Objective-C 中,nilNSNull 是完全不同的。前者基本上是一个零值指针,后者是一个被理解为“空”的实际对象,最常用于集合中(例如NSSetNSArrayNSDictionary 等)。
    【解决方案2】:

    非常感谢this answer by Conrad Shultz 提供的许多提示和建议!我已按照那里的建议和提示进行操作。

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

    原来字符串必须传递给第二个参数,但我传递的是nil。已修复!

    【讨论】:

      猜你喜欢
      • 2011-06-14
      • 1970-01-01
      • 2015-09-06
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 2012-10-31
      • 1970-01-01
      相关资源
      最近更新 更多