NSOutlineView 子类崩溃 - NSRangeException

Posted

技术标签:

【中文标题】NSOutlineView 子类崩溃 - NSRangeException【英文标题】:Crash in NSOutlineView subclass - NSRangeException 【发布时间】:2015-04-10 23:25:51 【问题描述】:

我有一个 NSOutlineView 的子类,它监听 NSManagedObjectContext 更改通知并相应地更新 outlineView。我在某个时候遇到了一个奇怪的崩溃,我的用户正在报告(我无法自己重现)......崩溃本身就是一个直接的 NSRangeException:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSIndexSet initWithIndexesInRange:]: Range 18446744073709551614, 1 exceeds maximum index value of NSNotFound - 1'

但令人困惑的部分是发生这种情况的代码:

- (void) addedObject: (CommonListData *) item toExistingSection: (CommonListData *) existingSection atIndex: (NSInteger) index 

if (index != NSNotFound) 
    [self beginUpdates];
    [self insertItemsAtIndexes: [NSIndexSet indexSetWithIndex: index] inParent: existingSection withAnimation:NSTableViewAnimationEffectFade | NSTableViewAnimationSlideDown];
    [self endUpdates];

    NSInteger scrollPosition = [self rowForItem: item];
    if (scrollPosition != NSNotFound && scrollPosition !=0) 
        NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:scrollPosition - 1]; // crashes here

现在,如果我检查 NSNotFound 和 0,为什么 indexSetWithIndex:(scrollPosition-1) 仍然给出 NSRangeException? 我还可以检查什么来确保 scollPosition 有效或无效?

不确定这是否相关,但仅当我的核心数据堆栈连接到 iCloud 并且我得到 NSPersistentStoreDidImportUbiquitousContentChangesNotification 并且我使用上下文对通知执行 mergeChangesFromContextDidSaveNotification 时才会发生这种情况。

【问题讨论】:

我在一开始就检查(index != NSNotFound),所以它不应该...而且崩溃总是与NSIndexSet indexSetWithIndex:scrollPosition,所以不确定它是否重要 【参考方案1】:

-[NSOutlineView rowForItem:] 如果项目不在大纲中,则返回 -1(不是 NSNotFound)。所以,scrollPosition 是 -1,scrollPosition - 1 是 -2。 +[NSIndexSet indexSetWithIndex:] 采用 NSUInteger (当然)是无符号的,所以 -2 变为 18446744073709551614。

【讨论】:

大概就是这样。不太清楚为什么它会返回 -1 而不是 NSNotFound,但它在文档中这么说,并且由于遗留原因,他们可能无法在此时更改它。

以上是关于NSOutlineView 子类崩溃 - NSRangeException的主要内容,如果未能解决你的问题,请参考以下文章

自定义 NSMangedObject 访问器崩溃 NSOutlineView

编辑 NSOutlineView 项目后使用委托

NSOutlineView 和 NSTreeController 可以处理数千个对象吗?

从 NSOutlineView 中拖放

NSOutlineView 侧边栏帮助

NSOutlineView 不折叠项目