16

我一直想知道为什么 NSProxy 类如此重要。为什么一个对象需要将其实例变量保存在其他对象中?我需要示例来了解何时使用它。谢谢!

4

2 回答 2

11

NSProxy 在需要代理拦截时很有用,假设您的应用程序中有一些样式化的 UISearchBar,当用户开始输入时您会在其中删除搜索图标,这意味着您需要侦听 UISearchBarDelegate 方法-searchBar:textDidChange:但此方法已被侦听ViewController 执行搜索,以避免代码重复,您不想在每个 ViewController 中复制粘贴隐藏图标逻辑。要解决此问题,您可以创建NSProxy将 ViewController 引用为originalDelegate并将隐藏搜索图标助手引用为middleMan,然后在您的 NSProxy 实例中,您需要实现以下方法:

- (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;
} 

并将您的代理实例设置为 searchBar 委托:searchBar.delegate = proxy

于 2018-08-23T07:13:41.890 回答
10

示例 A:假设您正在编写一个对象持久层(如 CoreData,但当然要好得多;))。

假设您只需查看索引树就可以非常快速地完成对数据库中数千个项目的查询,而无需读取和初始化完整项目的成本。您可以使用 NSProxy 来实现延迟加载。使用您的索引表来定位对象的主键,但不是创建该对象,而是返回一个知道真实对象主键的 NSProxy。

只有当需要另一个数据库查找时,代理对象才会创建该项目并将所有未来的消息重定向到它。调用代码只会处理 NSProxy 项,而现在永远不会处理后台执行的延迟加载。

示例 B(这是 OS X,抱歉):当大纲层次结构中有两次相同的项目时,NSOutlineView 的行为非常奇怪。当您的应用程序中有智能组功能时,这是非常常见的问题。解决方案:在大纲视图中使用不同的代理,指向同一个对象。

于 2015-02-02T23:14:17.117 回答