【问题标题】:Exception raised- NSTextView delegate- textViewDidChangeSelection: notification引发异常 - NSTextView 委托 - textViewDidChangeSelection:通知
【发布时间】:2013-07-31 10:00:01
【问题描述】:

我正在创建我的第一个 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: 块进行调试,似乎上述方法总是抛出该异常。如果我更换:

range.location

(range.location-1)

仅当光标位于索引 0 时才会引发该异常。

有人知道发生了什么吗?

【问题讨论】:

  • range.location-1 在 self.textView.selectedRange==0 时将是一个无效数字(没有选择,或者它从一开始就开始。

标签: objective-c cocoa nstextview


【解决方案1】:

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

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

(NSDictionary *)attributesAtIndex:(NSUInteger)indexlongestEffectiveRange:(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 的原因。

【讨论】:

  • 感谢您的宝贵时间。它再次崩溃(范围或索引超出范围)。不应该初始化有效范围吗?是否有我可能遗漏的与 Interface Builder 相关的内容?
  • 好吧,你的 textView 属性必须是一个连接到 IB 中实际 NSTextView 的 IBOutlet。您是否检查了 selectedRange 值以查看它们是否有意义(selectedRange.location、selectedRange.length)?有效范围将由方法初始化(即&有效范围)。
  • 是的,我在@finally 有一个 NSLog(@try-@catch 块),它们非常好。 IBOutlet 已设置,textview 的委托也已设置。
  • 我的 Document 类 (Document.m) 中没有任何前缀这一事实是否会影响运行时?
  • 似乎要解决这个问题,当 selectedRange 长度为 0(即没有选择)时,您已经跳过该方法(请参阅我上面的编辑)。然后你需要一个'else'来确定没有选择时要做什么。
【解决方案2】:

这个帖子已经有一段时间了,但无论如何我找到了这个,它是否对任何人都有用:

调用 - 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];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 2019-09-20
    • 2013-02-13
    • 1970-01-01
    • 2018-03-21
    相关资源
    最近更新 更多