我一直想知道为什么NSProxy类如此重要。为什么对象需要将其实例变量保存在其他对象中?我需要一些例子来了解何时使用它。谢谢!
答案 0 :(得分:7)
示例A:想象一下,您正在编写一个对象持久层(如CoreData,但当然要好得多;))。
假设您只需查看索引树即可快速完成对数据库中数千个项目的查询,而无需阅读和初始化完整项目的成本。 您可以使用NSProxy实现延迟加载。使用索引表来查找对象的主键,但不是创建该对象,而是返回一个知道真实对象主键的NSProxy。
仅当需要另一个数据库查找时,代理对象才会创建该项并将所有将来的消息重定向到该项。调用代码只处理NSProxy项目,现在从不关于在引擎盖下执行的延迟加载。
示例B(这是OS X,抱歉):当轮廓层次结构中有相同的项目两次时,NSOutlineView的行为非常奇怪。在应用中使用智能组功能时非常常见的问题。解决方案:在大纲视图中使用不同的代理,指向同一个对象。
答案 1 :(得分:4)
在需要委托拦截的情况下,NSProxy非常有用,例如,您的应用中有一些样式化的UISearchBar,在其中,当用户开始输入内容时,您会删除搜索图标,这意味着您需要监听UISearchBarDelegate方法{{1} },但是执行搜索的ViewController已经侦听了此方法,以避免重复代码,您不想在每个ViewController中都复制粘贴隐藏图标逻辑。要解决此问题,您可以创建-searchBar:textDidChange:
,该参考将以 originalDelegate 的形式引用ViewController,以 middleMan 的形式显示隐藏的搜索图标助手,然后在您的NSProxy实例中需要实现以下方法:
NSProxy
并将您的代理实例设置为searchBar委托:- (void)forwardInvocation:(NSInvocation *)invocation
{
if ([self.middleMan respondsToSelector:invocation.selector])
{
//Note: probably it's better to provide a copy invocation
[invocation invokeWithTarget:self.middleMan];
}
if ([self.originalDelegate respondsToSelector:invocation.selector])
{
[invocation invokeWithTarget:self.originalDelegate];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
id result = [self.originalDelegate methodSignatureForSelector:sel];
if (!result) {
result = [self.middleMan methodSignatureForSelector:sel];
}
return result;
}