IOS Class uses NSProxy and NSObject to design the differences between proxy classes, nsproxynsobject
It is often found that different programmers use different methods to create proxy classes that require message forwarding. Some adopt NSObject, while others use NSProxy. both are the base classes in the Foundation framework.<NSObject>
This interface is used by NSProxy in terms of naming and documentation. even so, they all define the same message forwarding interface, so what is the difference between the two in doing this.
First, paste the most basic implementation code for creating a proxy class.
Inherited from NSProxy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
@interface THProxyA : NSProxy @property (nonatomic, strong) id target; @end
@implementation THProxyA
- (id)initWithObject:(id)object { self.target = object; return self; }
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { return [self.target methodSignatureForSelector:selector]; }
- (void)forwardInvocation:(NSInvocation *)invocation { [invocation invokeWithTarget:self.target]; }
@end
|
Inherited from NSObject
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
@interface THProxyB : NSObject @property (nonatomic, strong) id target; @end
@implementation THProxyB
- (id)initWithObject:(id)object { self = [super init]; if (self) { self.target = object; } return self; }
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { return [self.target methodSignatureForSelector:selector]; }
- (void)forwardInvocation:(NSInvocation *)invocation { [invocation invokeWithTarget:self.target]; }
@end
|
The code is basically the same, except for the differences in the standard writing details during initialization, because the NSProxy base class does not define the default init method.
1. The test shows that the following two<NSObject>
The interface defined in is inconsistent between the two:
1 2 3 4 5 6 7 8 9
|
NSString *string = @"test"; THProxyA *proxyA = [[THProxyA alloc] initWithObject:string]; THProxyB *proxyB = [[THProxyB alloc] initWithObject:string];
NSLog(@"%d", [proxyA respondsToSelector:@selector(length)]); NSLog(@"%d", [proxyB respondsToSelector:@selector(length)]);
NSLog(@"%d", [proxyA isKindOfClass:[NSString class]]); NSLog(@"%d", [proxyB isKindOfClass:[NSString class]]);
|
The results will output different conclusions:
That is to say, the proxy class inherited from NSObject will not automatically forward the respondsToSelector: And isKindOfClass: methods, but the proxy class inherited from NSProxy is acceptable. Test<NSObject>
The other interfaces defined in are the same.
2. The methods defined in all Category of NSObject cannot be forwarded in THProxyB.
For example, valueForKey is a method defined in the NSObject Category of NSKeyValueCoding.
1 2
|
NSLog(@"%@",[proxyA valueForKey:@"length"]); NSLog(@"%@",[proxyB valueForKey:@"length"]);
|
The first sentence of this Code can run correctly, but the second line will throw an exception. The final reason for analysis is actually very simple, because valueForKey: is the method defined in the NSObject Category, enable NSObject to have such an interface, and message Forwarding is to seek objects that can be processed through forwardInvocation only when the recipient cannot process the message.
3. Conclusion: It seems that NSProxy is indeed more suitable for implementing the proxy class for message forwarding, because as an abstract class, NSProxy itself can process very small methods (only<NSObject>
Some methods defined in the interface), so other methods can be forwarded to the objects to be proxies as expected.