[Depth study iOS development (a)] Objective-C Reflection (Objective-C reflection)

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

 

Reference: https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Introduction/Introduction.html

 

Reproduced in: https: //www.cnblogs.com/dyingbleed/archive/2013/05/05/3029547.html

Guess you like

Origin blog.csdn.net/weixin_33871366/article/details/93301866