引发异常 - NSTextView委托 - textViewDidChangeSelection:通知

时间:2013-07-31 10:00:02

标签: objective-c cocoa nstextview

我正在创建我的第一个Mac应用程序,一个文本编辑器。它是基于文档的,Document.xib有一个nstextview。我已将Document类作为textview的委托。我正在实施该方法:

-(void)textViewDidChangeSelection:(NSNotification *)notification
{
NSRange range=self.textView.selectedRange;
NSLog(@" %@ ",[[self.textView textStorage] attributesAtIndex: range.location
                                              effectiveRange: &range]); 

我将使用NSLog内部的方法调用来获取所选文本的属性,并从该通知方法更新“下划线”按钮(按下 或不)。  问题是当应用程序运行时我按下一个键会引发异常:     一个未被捕获的例外被提出

*** -[NSConcreteTextStorage attributesAtIndex:effectiveRange:]: Range or index   
out of bounds

我尝试通过@try调试:@catch:block,似乎上面的方法总是抛出异常。如果我更换:

range.location

(range.location-1)

只有当光标位于索引0时才抛出该异常。

有谁知道发生了什么事?

2 个答案:

答案 0 :(得分:0)

effectiveRange 不是方法用于确定要扫描属性的范围的范围。在返回时,它将包含属性和值与索引attributeAtIndex相同的范围(即该方法将为您的范围变量指定不同的值)。

如果要限制方法用于查找所选范围的属性的范围,请使用以下方法并将rangeLimit设置为所选范围:

(NSDictionary *)attributesAtIndex:(NSUInteger)index longestEffectiveRange:(NSRangePointer)aRange inRange:(NSRange)rangeLimit

-(void)textViewDidChangeSelection:(NSNotification *)notification
{
    NSRange selectedRange=self.textView.selectedRange;
    NSRange effectiveRange;
    if(selectedRange.length > 0) {
        NSLog(@" %@ ",[[self.textView textStorage] attributesAtIndex:selectedRange.location
       longestEffectiveRange:&effectiveRange inRange:selectedRange]); 
    }
}

当selectedRange长度为0时,该方法似乎不起作用。这就是在调用selectedRange.length之前检查它的原因。

答案 1 :(得分:0)

这个帖子已经有一段时间了,但无论如何我发现了这个,如果它对任何人都有用:

调用 - attributesAtIndex:当range.length == 0时仍然可以正常工作,但是当位置在字符串的末尾时它会失败。这显然是一个错误,因为范围{string_length,0}是一个有效范围。

为了解决这个问题,我使用了-typingAttributes:它给出了当前输入样式的属性。

NSRange currange = [self.textViewEditor selectedRange];
NSLog(@"range %@", NSStringFromRange(currange));
NSDictionary *dict;
if (currange.length==0)
    dict = [self.textViewEditor typingAttributes];
else
    dict = [self.textViewEditor.textStorage attributesAtIndex:currange.location effectiveRange:&range];