Objective-C Reflection (Objective-C reflection)
NSObject method
With few exceptions, Cocoa majority of classes are subclasses of NSObject, so most objects inherit the methods it defines.
NSObject provides some simple query runtime system information approach:
- - (BOOL)isKindOfClass:(Class)aClass
Returns a Boolean value that indicates whether the receiver is an instance of given class or an instance of any class that inherits from that class. - - (BOOL)isMemberOfClass:(Class)aClass
Returns a Boolean value that indicates whether the receiver is an instance of a given class. - - (BOOL)respondsToSelector:(SEL)aSelector
Returns a Boolean value that indicates whether the receiver implements or inherits a method that can respond to a specified message. - - (BOOL)conformsToProtocol:(Protocol *)aProtocol
Returns a Boolean value that indicates whether the receiver conforms to a given protocol.
if ([@"Hello World" isKindOfClass:[NSObject class]]) { NSLog(@"YES"); } else { NSLog(@"NO"); } if ([@"Hello World" isMemberOfClass:[NSObject class]]) { NSLog(@"YES"); } else { NSLog(@"NO"); } if ([self respondsToSelector:@selector(test)]) { NSLog(@"YES"); } else { NSLog(@"NO"); } if ([self conformsToProtocol:@protocol(NSObject)]) { NSLog(@"YES"); } else { NSLog(@"NO"); }
Messaging
In Objective-C, the message will be binding until runtime method to achieve.
The expression compiler message (message expression) into calls Objective-C run-time functions objc_msgSend
[receiver message] -> objc_msgSend(receiver, selector)
id objc_msgSend(id theReceiver, SEL theSelector, ...)
Sends a message with a simple return value to an instance of a class.
Use objc_msgSend functions necessary to introduce Objective-C run-time file header: #import <ObjC / message.h>
[self test];
objc_msgSend(self, @selector(test));
The method defined in NSObject methodForSelector by class: You can request a pointer process implemented method (Procedure) a.
- (IMP)methodForSelector:(SEL)aSelector
Locates and returns the address of the receiver’s implementation of a method so it can be called as a function.
Call IMP, the first two parameters need to pass, the received message is a first object, the second is a selector.
IMP test = [self methodForSelector:@selector(test)];
test(self, @selector(test));
Dynamic method
In some cases, we want to provide dynamic methods.
Objective-C to tell the compiler by using @dynamic statement attribute (property), property (property) associated methods will be dynamically provided.
You can be achieved by a method resolveInstanceMethod: and resolveClassMetho: an instance of the corresponding class and method to implement a dynamic selector.
- + (BOOL)resolveInstanceMethod:(SEL)name
Dynamically provides an implementation for a given selector for an instance method. - + (BOOL)resolveClassMethod:(SEL)name
Dynamically provides an implementation for a given selector for a class method.
Define a User class
In the .h file that defines the attributes name
In the past, will be in the corresponding .m files using @synthesize statement attribute name, the compiler will automatically generate setter and getter methods
However, when using @dynamic declare property name, you must provide your own corresponding setter and getter methods
Override + (BOOL)resolveInstanceMethod:(SEL)name 方法
When a class instance invokes - (void) setName: (NSString) aName or - (NSString *) name method, it provides a method for dynamically implemented
#import <Foundation/Foundation.h> @interface User : NSObject { NSString *name; } @property (nonatomic, retain) NSString *name; @end
#import "User.h" #import <objc/runtime.h> @implementation User @dynamic name; - (void)dynamicSetName:(NSString *) aName { if (name != nil) { [name release]; name = nil; } [aName retain]; name = aName; } - (NSString *)dynamicName { return name; } + (BOOL)resolveInstanceMethod:(SEL)sel { NSLog(@"Instance Method: %@", NSStringFromSelector(sel)); if ([@"setName:" isEqualToString:NSStringFromSelector(sel)]) { class_addMethod([self class], sel, [self instanceMethodForSelector:@selector(dynamicSetName:)], "v@:"); return YES; } else if ([@"name" isEqualToString:NSStringFromSelector(sel)]) { class_addMethod([self class], sel, [self instanceMethodForSelector:@selector(dynamicName)], "@"); return YES; } return [super resolveInstanceMethod:sel]; } @end
Reproduced in: https: //www.cnblogs.com/dyingbleed/archive/2013/05/05/3029547.html