I have been wondering why is NSProxy class so important. Why does an object need to keep its instance variables inside other objects? I need examples to understand when to use i
Example A: Imagine you'd be writing an object persistence layer (like CoreData, but much better of course ;) ).
Let's say you can fulfill a query for thousands of items in your database really quick by just looking at the index-tree, without the cost of reading and initializing the complete item. You could use NSProxy to implement lazy-loading. Use your index table to locate the primary key of the object, but instead of creating that object, return an NSProxy that knows the primary key of the real object.
Only when another database lookup is required, the proxy object creates the item and redirect all future messages to it. The calling code would only deal with the NSProxy item, and never now about the lazy-loading performed under the hood.
Example B (this is OS X, sorry): NSOutlineView behaves really odd, when you have the same item in the outline hierarchy twice. Very common problem when you have a smart group feature in your app. The solution: use different proxies in the outline view, pointing to the same object.
NSProxy is useful when there is a need for delegate interception, let's say you have some styled UISearchBar across your app, in which you remove the search icon when user starts typing, it means you need to listen UISearchBarDelegate method -searchBar:textDidChange:
but this method is already listened by ViewController which performs searching, to avoid code duplications you don't want to copy-paste hiding icon logic in every your ViewController. To solve this problem you can create NSProxy
which will have reference to your ViewController as originalDelegate and your hiding search icon helper as middleMan, then in your NSProxy instance you need implement following methods:
- (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;
}
And set your proxy instance to searchBar delegate: searchBar.delegate = proxy