I’ll start with an example of NSProxy use.
Example of using NSProxy
@interface BDWeakProxy : NSProxy
@property (nonatomic, weak) id target;
@end
@implementation BDWeakProxy
- (instancetype)initWithTarget:(id)target {
self.target = target;
return self;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation invokeWithTarget:self.target];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
return [self.target methodSignatureForSelector:sel];
}
@end
Copy the code
According to the official documentation, by overriding these two methods, you can use BDWeakProxy to forward messages to Target.
But what about NSObject?
@interface BDWeakProxy : NSObject
@property (nonatomic, weak) id target;
@end
@implementation BDWeakProxy
- (instancetype)initWithTarget:(id)target {
self = [super init];
if (self) {
self.target = target;
}
return self;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation invokeWithTarget:self.target];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
return [self.target methodSignatureForSelector:sel];
}
@end
Copy the code
Can also do message forwarding, what is the difference between the two?
NSProxy is different
NSProxy
Class is notinit
methodsNSProxy
Is an abstract class, and the parent class is notNSObject
- Some of the
NSObject
In some waysNSProxy
Do not implement NSProxy
The message forwarding mechanism of
The message forwarding mechanism for a general object is shown below.
There is no need to explain the message forwarding mechanism. The two examples above finally use the message forwarding mechanism, and the message is forwarded to target in the last step.
As mentioned in this article, a proxy class that inherits from NSObject does not automatically forward respondsToSelector: and isKindOfClass: methods, whereas a proxy class that inherits from NSProxy does. The other interfaces defined in the test behave the same.
Practical reasons:
NSProxy
Do not implementrespondsToSelector:
andisKindOfClass:
These two methods are therefore forwarded.NSObject
There are implementation.
NSProxy message forwarding mechanism
The focus is on the NSProxy approach.
NS_ROOT_CLASS
@interface NSProxy <NSObject> {
Class isa;
}
+ (id)alloc;
+ (id)allocWithZone:(nullable NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
+ (Class)class;
- (void)forwardInvocation:(NSInvocation *)invocation;
- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel NS_SWIFT_UNAVAILABLE("NSInvocation and related APIs not available");
- (void)dealloc;
- (void)finalize;
@property (readonly, copy) NSString *description;
@property (readonly, copy) NSString *debugDescription;
+ (BOOL)respondsToSelector:(SEL)aSelector;
- (BOOL)allowsWeakReference NS_UNAVAILABLE;
- (BOOL)retainWeakReference NS_UNAVAILABLE;
@end
Copy the code
NSProxy
andNSObject
The same isNS_ROOT_CLASS
, which is the root classNSProxy
Is to realize the@protocol NSObject
“Rather than inheritance@interface NSObject
NSProxy
Instead of the first and second steps of message forwarding, go straight to the third step,NSProxy
There is no corresponding method implemented
In fact, NSProxy does not implement any instance methods, although the – (Class) Class method is implemented.
This makes the
NSProxy
It’s pure, it’s clean, it’s notNSObject
There are many categories, many ways not to forwardNSProxy
Method is little, alwaysNSProxy
Methods that are not implemented can be forwarded, which means that almost any method can be forwardedNSProxy
Proxy classes can be designed to be more pure
The purpose of the NSProxy
- AOP
- The proxy pattern, the Decorator pattern, and here is a simple demo for reference
- Multiple inheritance, which simulates multiple inheritance by referencing multiple targets.