One 、 brief introduction
stay iOS Application development , Customizing a class generally needs to inherit from NSObject Class or NSObject Subclass , however ,NSProxy Class does not inherit from NSObject Class or NSObject Subclass , It's a realization NSObject Abstract base class of protocol .
/* NSProxy.h
Copyright (c) 1994-2019, Apple Inc. All rights reserved.
*/
#import <Foundation/NSObject.h>
@class NSMethodSignature, NSInvocation;
NS_ASSUME_NONNULL_BEGIN
NS_ROOT_CLASS
@interface NSProxy <NSObject> {
__ptrauth_objc_isa_pointer 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 API_UNAVAILABLE(macos, ios, watchos, tvos);
- (BOOL)retainWeakReference API_UNAVAILABLE(macos, ios, watchos, tvos);
// - (id)forwardingTargetForSelector:(SEL)aSelector;
@end
NS_ASSUME_NONNULL_END
NSProxy Its function is to act as a principal-agent , Forward the message to a real object or an object loaded by yourself .
To learn more about NSProxy The role of classes , Let's implement a colleague call NSMutableString and NSMutableArray Delegate classes of methods in two classes , Simulate multiple inheritance .
First create TargetProxy class , Let him inherit NSProxy. And implement the initialization method .
@interface TargetProxy : NSProxy
/// Initialization method , Save two real objects
/// @param object1 The first real object
/// @param object2 The second real object
- (instancetype)initWithObject1:(id)object1 object2:(id)object2;
@end
@implementation TargetProxy {
// Save the first real object to forward the message to
// The method call priority of the first real object will be higher than that of the second real object
id _realObject1;
// Save the second real object to forward the message to
id _realObject2;
}
- (instancetype)initWithObject1:(id)object1 object2:(id)object2 {
_realObject1 = object1;
_realObject2 = object2;
return self;
}
And then in TargetProxy.m In file , rewrite - methodSignatureForSelector: Get the real object method signature , And rewrite - forwardInvocation: Method , Call real object methods .
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
// obtain _realObject1 in sel Method signature for
NSMethodSignature *signature = [_realObject1 methodSignatureForSelector:sel];
// If _realObject1 There is this method in , Then return the signature of the method
// without , return _realObject1 Method signature
if (signature) {
return signature;
}
// obtain _realObject1 Medium sel Method signature for
signature = [_realObject2 methodSignatureForSelector:sel];
return signature;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
// Get the real object that owns the method
id target = [_realObject1 methodSignatureForSelector:[invocation selector]] ? _realObject1 : _realObject2;
// Execution method
[invocation invokeWithTarget:target];
}
Last , Conduct Demo test
- (void)testTargetProxy {
NSMutableString *string = [NSMutableString string];
NSMutableArray *array = [NSMutableArray array];
id proxy = [[TargetProxy alloc] initWithObject1:string object2:array];
[proxy appendString:@"This "];
[proxy appendString:@"is "];
[proxy addObject:string];
[proxy appendString:@"a "];
[proxy appendString:@"test!"];
NSLog(@"The string is length is: %@", [proxy valueForKey:@"length"]);
NSLog(@"count should be 1, it is %ld", [proxy count]);
if ([[proxy objectAtIndex:0] isEqualToString:@"This is a test!"]) {
NSLog(@"Appending successful.");
} else {
NSLog(@"Appending failed,, got: '%@'", proxy);
}
}
Run the above code , The input log is as follows :
2022-04-02 11:30:35.957145+0800 Demo[19783:586710] SuccessFully create Delegere Proxy automatically.
2022-04-02 11:30:35.959722+0800 Demo[19783:586710] The string is length is: 15
2022-04-02 11:30:35.960175+0800 Demo[19783:586710] count should be 1, it is 1
2022-04-02 11:30:40.086227+0800 Demo[19783:586710] Appending successful.
Above description , We use TargetProxy Class successfully implements message forwarding .
Of course , In most cases , Use NSObject Class can also implement message forwarding , Implementation and NSProxy similar , But in most cases NSProxy More appropriate . because :
- NSProxy Class implements the following NSObject The basic methods required by the protocol in the inner base class
- adopt NSObject The proxy class implemented by class will not automatically forward NSObject The method in the agreement
- adopt NSObject The proxy class implemented by class will not automatically forward NSObject Methods in the category
Use NSProxy More articles about message forwarding
- iOS Message forwarding and NSProxy actual combat
The last update : 2018-01-17 One . Message distribution mechanism -NSObject stay iOS In development , The way to call an object is to send a message to the object . Understanding the message distribution mechanism is very important for iOS Development is a very practical and powerful tool , Next I ...
- iOS Development - forward
Message forwarding is OC Important features of runtime ,Objective-C The main task of the runtime is to be responsible for message distribution , We are in development "unrecognized selector sent to instance xx& ...
- runtime Message forwarding mechanism
Objective-C Expanded C Language , And added object-oriented features and Smalltalk Type of messaging mechanism . And the core of this extension is an application C and Compiled language Written Runtime library . It is Objective- ...
- iOS - Message forwarding processing
Detailed runtime Basics NSInvocation Introduce NSHipster-Swizzling Objective-C Method Analysis of related methods Type Encodings Objc yes OOP, So there's polymorphism . When ...
- iOS Message forwarding mechanism
The pre knowledge of this blog is OC The messaging mechanism of , If you don't know about it yet , Please study first , Look at this one again . In this blog, I try to talk about it in a spoken way like PPT Let's talk about this knowledge point . Let's think about a problem , If the object cannot be solved after receiving ...
- ios Message forwarding
Sometimes the data in the interface document of the server is string type , In this case, you will directly assign it to a label. The problem is coming. , Sometimes this string It is indeed. string, No problem , Sometimes it's NSNumber, Of course, no matter three ...
- Effective Objective-C 2.0 — The first 12 strip : Understand message forwarding mechanism
11 This article explains the message passing mechanism of objects 12 What happens when an object receives an unreadable message , Will start “ forward ”(message forwarding) Mechanism , If the object cannot respond to a selector , Then enter the message forwarding process . ...
- runtime Message forwarding of
Preface In the last article, we first tasted runtime Black magic of , You can get the name of the member variable at the compilation stage of the program , Features and dynamically adding attributes to objects , In the next section, we will learn more about OC Message sending mechanism of . If you haven't touched it before runti ...
- iOS forward
forward delegate and protocol Category forward Direction someObject Send a message , but runtime system When the implementation of the corresponding method cannot be found in the current class and parent class ,runt ...
- objc_msgSend Messaging learning notes – forward
The article is objc_msgSend Messaging learning notes – Object method message passing process Continue to explore the source code on the basis of , Please read the above first . Message forwarding mechanism (message forwarding) Objective-C In the call to ...
Random recommendation
- Sharepoint Learning notes — Exercise series --70-576 Problem solving -(Q66-Q68)
Question 66 You are designing an application that will use a timer job that will run each night to s ...
- [AngularJS] Directive Definition Objects (DDO)
This function that we just set up is what's called a link function, and it's actually a very small p ...
- Web Inquiry and sorting of learning resources and manuals
Getting started html.css.js.jQuery:http://www.w3school.com.cn/, bootstrap.nodejs.php.jQuery introduction :http://www.runoob. ...
- matching “is outside location”
<pre name="code" class="html">is outside location How to match ? . Match all single characters except line breaks , Usually ...
- log4j Learning notes
stay java Import package in file : import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; At the end of the day ...
- Apache Arrow Memory data
1. summary Apache Arrow yes Apache A top-level project newly hatched by the foundation . It's designed to be a cross platform data layer , To speed up big data analysis projects . 2. Content Now there are many big data processing models , The user should ...
- flume Installation and introduction examples
1. How to install ? 1) Will download flume package , Unzip to /home/hadoop Directory 2) modify flume-env.sh The configuration file , Mainly JAVA_HOME Variable is set [email protected]:/home/hadoo ...
- xueping wang Record 2
In the use of easyui Of tabs When , On the tab Can be turned off Button It doesn't show ? tabs Of closable:true attribute , In fact, it is through Label header tabHeader At the back of , Add a hyperlink ...
- Activity Of task Task stack
from http://blog.csdn.net/liuhe688/article/details/6761337 The ancients had a lot of knowledge , When you are young, you are old . It's on paper , Never know that you have to do it . The Southern Song Dynasty . Lu You < Winter night reading ...
- linux Medium cd
cd command example [email protected]:~$ cd /home/hling/ desktop /[email protected]:~/ desktop /huang$ cd [email protected]:~/ desktop $ cd ..hl ...