2015-10-04 76 views
1

有没有办法将NSArrayController的内容数组绑定到非技术上不是数组的自定义对象,但其行为如同一个?将NSArrayController的内容数组绑定到一个自定义(非数组)对象

具体而言,我试图将NSTableView绑定到PDFDocument(因此,该表中的每行为PDFPage)。 PDFDocument不是数组,但有许多相同类型的方法(如insertPage:atIndex:removePageAtIndex:等)。

我最终想写一个包装,将PDFDocument的方法转换为NSMutableArray的方法,但我不确定要采取什么方法。我做了一些尝试,绑定似乎不能正常工作。

或者更具体地说,将表绑定到PDFDocument的页面以模仿PDFThumbnailView(对于那些了解PDFKit的人)的任何方式?

谢谢!

回答

2

绑定建立在键值观察和键值编码上。

要仅查询PDFDocument的页面,阵列控制器和绑定将使用-valueForKey:。如Key-Value Coding Programming Guide: Accessor Search Implementation Details所述,这将使用各种命名模式来搜索简单的吸气剂。由于“pages”属性没有简单的getter,它将搜索indexed collection accessors。特别是,它会寻找-countOfPages-objectInPagesAtIndex:-pagesAtIndexes:之一。这些在PDFDocument中都不存在,但存在非常类似的方法。您可以使用类别的可用方法来实现这些。

但是,如果PDFDocument将要改变它的页面列表,并且您希望阵列控制器自动接收这些更改,则会出现问题。必须以符合KVO的方式对属性进行修改,以便绑定才能接受更改。如果插入例程名为-insertObject:inPagesAtIndex:,那将是KVO兼容的,但事实并非如此。它被命名为-insertPage:atIndex:,KVO无法识别。这不是您可以使用某个类别修复的问题,因为重要的是使用什么方法,而不是仅有哪些方法可用。

你可以尝试使用的PDFDocument一个子类覆盖-insertPage:atIndex:前,并呼吁通过超后打电话到-willChange:valuesAtIndexes:forKey:-didChange:valuesAtIndexes:forKey:。但是,并不能保证所有的插入操作都通过公共方法。有时候类可能会直接修改它的内部状态而不调用任何子类可以正确覆盖的方法。 (所有相同的适用于去除方法。)

如果你所有的突变是通过你的代码发起肯定,可以使你的代码中使用了符合国际志愿者组织的方法,你就必须执行在一个类别或子类中。

+0

非常感谢这么一个彻底的答案 - 令人难以置信。我确实试图通过绑定来改变'PDFDocument',这就解释了为什么它不起作用。子类的想法听起来像是首先尝试的最佳方法。再次感谢你的帮助。 –

+0

如果您试图让绑定变更文档,那么您需要实现索引集合变异访问器:'-insertObject:inPagesAtIndex:'或'-insertPages:atIndexes:'和'-removeObjectFromPagesAtIndex之一:'或'-removePagesAtIndexes:'。那些可以调用不符合KVC或KVO预期的超类方法。如果你实现了这些,你不必也不应该调用'-willChange ...'或'-didChange ...'。这是因为KVO已经知道要挂钩这些方法来自动生成更改通知。这可以通过一个类别完成。 –