Реальные примеры, где класс NSProxy полезен и почему?
Мне было интересно, почему класс NSProxy так важен. Почему объект должен хранить свои переменные экземпляра внутри других объектов? Мне нужны примеры, чтобы понять, когда его использовать. Спасибо!
2 ответа
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
Пример А. Представьте, что вы пишете слой персистентности объекта (например, CoreData, но, конечно, гораздо лучше;)).
Допустим, вы можете выполнить запрос для тысяч элементов в вашей базе данных очень быстро, просто взглянув на дерево индексов, без затрат на чтение и инициализацию всего элемента. Вы можете использовать NSProxy для реализации отложенной загрузки. Используйте свою индексную таблицу, чтобы найти первичный ключ объекта, но вместо создания этого объекта верните NSProxy, который знает первичный ключ реального объекта.
Только когда требуется другой поиск в базе данных, прокси-объект создает элемент и перенаправляет на него все будущие сообщения. Вызывающий код будет иметь дело только с элементом NSProxy, и никогда больше с отложенной загрузкой, выполняемой изнутри.
Пример B (это OS X, извините): NSOutlineView ведет себя очень странно, когда у вас есть один и тот же элемент в иерархии структуры дважды. Очень распространенная проблема, когда в вашем приложении есть функция умной группы. Решение: использовать разные прокси в виде структуры, указывая на один и тот же объект.